source: trunk/src/user32/win32wbase.cpp@ 2672

Last change on this file since 2672 was 2672, checked in by sandervl, 26 years ago

DC changes + commented out shell position update

File size: 112.8 KB
Line 
1/* $Id: win32wbase.cpp,v 1.156 2000-02-06 22:00:24 sandervl Exp $ */
2/*
3 * Win32 Window Base Class for OS/2
4 *
5 * Copyright 1998-2000 Sander van Leeuwen (sandervl@xs4all.nl)
6 * Copyright 1999 Daniela Engert (dani@ngrt.de)
7 * Copyright 1999-2000 Christoph Bratschi (cbratschi@datacomm.ch)
8 *
9 * Parts based on Wine Windows code (windows\win.c)
10 *
11 * Copyright 1993, 1994, 1996 Alexandre Julliard
12 * 1995 Alex Korobka
13 *
14 * TODO: Not thread/process safe
15 *
16 * NOTE: Client rectangle always relative to frame window; window rectangle in screen coordinates
17 *
18 * Project Odin Software License can be found in LICENSE.TXT
19 *
20 */
21#include <os2win.h>
22#include <win.h>
23#include <stdlib.h>
24#include <string.h>
25#include <stdarg.h>
26#include <assert.h>
27#include <misc.h>
28#include <heapstring.h>
29#include <win32wbase.h>
30#include <winres.h>
31#include "wndmsg.h"
32#include "oslibwin.h"
33#include "oslibmsg.h"
34#include "oslibutil.h"
35#include "oslibgdi.h"
36#include "oslibres.h"
37#include "oslibdos.h"
38#include "syscolor.h"
39#include "win32wndhandle.h"
40#include "dc.h"
41#include "pmframe.h"
42#include "win32wdesktop.h"
43#include "pmwindow.h"
44#include "controls.h"
45#include <wprocess.h>
46#include "winmouse.h"
47#include <win\hook.h>
48#include <menu.h>
49#define INCL_TIMERWIN32
50#include "timer.h"
51
52#define SC_ABOUTWINE (SC_SCREENSAVE+1)
53#define SC_PUTMARK (SC_SCREENSAVE+2)
54
55/* bits in the dwKeyData */
56#define KEYDATA_ALT 0x2000
57#define KEYDATA_PREVSTATE 0x4000
58
59void PrintWindowStyle(DWORD dwStyle, DWORD dwExStyle);
60
61static fDestroyAll = FALSE;
62//For quick lookup of current process id
63static ULONG currentProcessId = -1;
64
65//******************************************************************************
66//******************************************************************************
67Win32BaseWindow::Win32BaseWindow(DWORD objType) : GenericObject(&windows, objType)
68{
69 Init();
70}
71//******************************************************************************
72//******************************************************************************
73Win32BaseWindow::Win32BaseWindow(CREATESTRUCTA *lpCreateStructA, ATOM classAtom, BOOL isUnicode)
74 : GenericObject(&windows, OBJTYPE_WINDOW), ChildWindow()
75{
76 Init();
77 this->isUnicode = isUnicode;
78 CreateWindowExA(lpCreateStructA, classAtom);
79}
80//******************************************************************************
81//******************************************************************************
82void Win32BaseWindow::Init()
83{
84 isUnicode = FALSE;
85 fFirstShow = TRUE;
86 fIsDialog = FALSE;
87 fIsModalDialogOwner = FALSE;
88 OS2HwndModalDialog = 0;
89 fInternalMsg = FALSE;
90 fNoSizeMsg = FALSE;
91 fIsDestroyed = FALSE;
92 fDestroyWindowCalled = FALSE;
93 fCreated = FALSE;
94 fTaskList = FALSE;
95 fParentDC = FALSE;
96
97 windowNameA = NULL;
98 windowNameW = NULL;
99 wndNameLength = 0;
100
101 userWindowLong = NULL;;
102 nrUserWindowLong = 0;
103
104 magic = WIN32PM_MAGIC;
105 OS2Hwnd = 0;
106 OS2HwndFrame = 0;
107 hSysMenu = 0;
108 Win32Hwnd = 0;
109
110 if(HwAllocateWindowHandle(&Win32Hwnd, (ULONG)this) == FALSE)
111 {
112 dprintf(("Win32BaseWindow::Init HwAllocateWindowHandle failed!!"));
113 DebugInt3();
114 }
115
116 posx = posy = 0;
117 width = height = 0;
118
119 dwExStyle = 0;
120 dwStyle = 0;
121 win32wndproc = 0;
122 hInstance = 0;
123 dwIDMenu = 0; //0xFFFFFFFF; //default -1
124 userData = 0;
125 contextHelpId = 0;
126 hotkey = 0;
127
128 pOldFrameProc = NULL;
129
130 hwndLinkAfter = HWND_BOTTOM;
131 flags = 0;
132 isIcon = FALSE;
133 lastHitTestVal = HTOS_NORMAL;
134 owner = NULL;
135 windowClass = 0;
136
137 iconResource = NULL;
138
139 EraseBkgndFlag = TRUE;
140 PSEraseFlag = FALSE;
141 SuppressEraseFlag = FALSE;
142
143 horzScrollInfo = NULL;
144 vertScrollInfo = NULL;
145
146 ownDC = 0;
147 hWindowRegion = 0;
148 hClipRegion = 0;
149
150 if(currentProcessId == -1)
151 {
152 currentProcessId = GetCurrentProcessId();
153 }
154 dwThreadId = GetCurrentThreadId();
155 dwProcessId = currentProcessId;
156}
157//******************************************************************************
158//todo get rid of resources (menu, icon etc)
159//******************************************************************************
160Win32BaseWindow::~Win32BaseWindow()
161{
162 OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, 0);
163 OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, 0);
164
165 if(!fDestroyAll && getParent() && getParent()->getFirstChild() == this && getNextChild() == NULL)
166 {
167 //if we're the last child that's being destroyed and our
168 //parent window was also destroyed, then we delete the parent object
169 if(getParent()->IsWindowDestroyed())
170 {
171 dprintf(("Last Child (%x) destroyed, get rid of our parent window (%x)", getWindowHandle(), getParent()->getWindowHandle()));
172 delete getParent();
173 setParent(NULL); //or else we'll crash in the dtor of the ChildWindow class
174 }
175 }
176 else
177 if(fDestroyAll) {
178 dprintf(("Destroying window %x %s", getWindowHandle(), windowNameA));
179 setParent(NULL); //or else we'll crash in the dtor of the ChildWindow class
180 }
181
182 if(isOwnDC())
183 releaseOwnDC(ownDC);
184
185 if(Win32Hwnd)
186 HwFreeWindowHandle(Win32Hwnd);
187
188 if(userWindowLong)
189 free(userWindowLong);
190
191 if(windowNameA) {
192 free(windowNameA);
193 windowNameA = NULL;
194 }
195 if(windowNameW) {
196 free(windowNameW);
197 windowNameW = NULL;
198 }
199 if(vertScrollInfo) {
200 free(vertScrollInfo);
201 vertScrollInfo = NULL;
202 }
203 if(horzScrollInfo) {
204 free(horzScrollInfo);
205 horzScrollInfo = NULL;
206 }
207}
208//******************************************************************************
209//******************************************************************************
210void Win32BaseWindow::DestroyAll()
211{
212 fDestroyAll = TRUE;
213 GenericObject::DestroyAll(windows);
214}
215//******************************************************************************
216//******************************************************************************
217BOOL Win32BaseWindow::isChild()
218{
219 return ((dwStyle & WS_CHILD) != 0);
220}
221//******************************************************************************
222//******************************************************************************
223BOOL Win32BaseWindow::IsWindowUnicode()
224{
225 dprintf2(("IsWindowUnicode %x %d", getWindowHandle(), WINPROC_GetProcType(getWindowProc()) == WIN_PROC_32W));
226 return (WINPROC_GetProcType(getWindowProc()) == WIN_PROC_32W);
227}
228//******************************************************************************
229//******************************************************************************
230#if 1
231BOOL Win32BaseWindow::CreateWindowExA(CREATESTRUCTA *cs, ATOM classAtom)
232{
233 char buffer[256];
234 POINT maxSize, maxPos, minTrack, maxTrack;
235
236#ifdef DEBUG
237 PrintWindowStyle(cs->style, cs->dwExStyle);
238#endif
239
240 sw = SW_SHOW;
241 SetLastError(0);
242
243 /* Find the parent window */
244 if (cs->hwndParent)
245 {
246 Win32BaseWindow *window = GetWindowFromHandle(cs->hwndParent);
247 if(!window) {
248 dprintf(("Bad parent %04x\n", cs->hwndParent ));
249 SetLastError(ERROR_INVALID_PARAMETER);
250 return FALSE;
251 }
252 /* Make sure parent is valid */
253 if (!window->IsWindow() )
254 {
255 dprintf(("Bad parent %04x\n", cs->hwndParent ));
256 SetLastError(ERROR_INVALID_PARAMETER);
257 return FALSE;
258 }
259 }
260 else
261 if ((cs->style & WS_CHILD) && !(cs->style & WS_POPUP)) {
262 dprintf(("No parent for child window\n" ));
263 SetLastError(ERROR_INVALID_PARAMETER);
264 return FALSE; /* WS_CHILD needs a parent, but WS_POPUP doesn't */
265 }
266
267 /* Find the window class */
268 windowClass = Win32WndClass::FindClass(cs->hInstance, (LPSTR)classAtom);
269 if (!windowClass)
270 {
271 GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) );
272 dprintf(("Bad class '%s'\n", buffer ));
273 SetLastError(ERROR_INVALID_PARAMETER);
274 return 0;
275 }
276#ifdef DEBUG
277 if(HIWORD(cs->lpszClass))
278 {
279 char *astring;
280
281 if(isUnicode) astring = UnicodeToAsciiString((LPWSTR)cs->lpszClass);
282 else astring = (char *)cs->lpszClass;
283
284 dprintf(("Window class %s", astring));
285 if(isUnicode) FreeAsciiString(astring);
286 }
287 else dprintf(("Window class %x", cs->lpszClass));
288#endif
289
290 /* Fix the lpszClass field: from existing programs, it seems ok to call a CreateWindowXXX
291 * with an atom as the class name, put some programs expect to have a *REAL* string in
292 * lpszClass when the CREATESTRUCT is sent with WM_CREATE
293 */
294 if (!HIWORD(cs->lpszClass) ) {
295 if (isUnicode) {
296 GlobalGetAtomNameW( classAtom, (LPWSTR)buffer, sizeof(buffer) );
297 }
298 else {
299 GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) );
300 }
301 cs->lpszClass = buffer;
302 }
303
304 /* Fix the coordinates */
305 if ((cs->x == CW_USEDEFAULT) || (cs->x == CW_USEDEFAULT16))
306 {
307// PDB *pdb = PROCESS_Current();
308
309 /* Never believe Microsoft's documentation... CreateWindowEx doc says
310 * that if an overlapped window is created with WS_VISIBLE style bit
311 * set and the x parameter is set to CW_USEDEFAULT, the system ignores
312 * the y parameter. However, disassembling NT implementation (WIN32K.SYS)
313 * reveals that
314 *
315 * 1) not only if checks for CW_USEDEFAULT but also for CW_USEDEFAULT16
316 * 2) it does not ignore the y parameter as the docs claim; instead, it
317 * uses it as second parameter to ShowWindow() unless y is either
318 * CW_USEDEFAULT or CW_USEDEFAULT16.
319 *
320 * The fact that we didn't do 2) caused bogus windows pop up when wine
321 * was running apps that were using this obscure feature. Example -
322 * calc.exe that comes with Win98 (only Win98, it's different from
323 * the one that comes with Win95 and NT)
324 */
325 if ((cs->y != CW_USEDEFAULT) && (cs->y != CW_USEDEFAULT16)) sw = cs->y;
326
327 /* We have saved cs->y, now we can trash it */
328#if 0
329 if ( !(cs->style & (WS_CHILD | WS_POPUP))
330 && (pdb->env_db->startup_info->dwFlags & STARTF_USEPOSITION) )
331 {
332 cs->x = pdb->env_db->startup_info->dwX;
333 cs->y = pdb->env_db->startup_info->dwY;
334 }
335#endif
336 cs->x = 0;
337 cs->y = 0;
338// }
339 }
340 if ((cs->cx == CW_USEDEFAULT) || (cs->cx == CW_USEDEFAULT16))
341 {
342#if 0
343 PDB *pdb = PROCESS_Current();
344 if ( !(cs->style & (WS_CHILD | WS_POPUP))
345 && (pdb->env_db->startup_info->dwFlags & STARTF_USESIZE) )
346 {
347 cs->cx = pdb->env_db->startup_info->dwXSize;
348 cs->cy = pdb->env_db->startup_info->dwYSize;
349 }
350 else
351 {
352#endif
353 cs->cx = 600; /* FIXME */
354 cs->cy = 400;
355// }
356 }
357
358 if (cs->x < 0) cs->x = 0;
359 if (cs->y < 0) cs->y = 0;
360
361 //Allocate window words
362 nrUserWindowLong = windowClass->getExtraWndWords();
363 if(nrUserWindowLong) {
364 userWindowLong = (ULONG *)_smalloc(nrUserWindowLong);
365 memset(userWindowLong, 0, nrUserWindowLong);
366 }
367
368 if ((cs->style & WS_CHILD) && cs->hwndParent)
369 {
370 SetParent(cs->hwndParent);
371 owner = GetWindowFromHandle(cs->hwndParent);
372 if(owner == NULL)
373 {
374 dprintf(("HwGetWindowHandleData couldn't find owner window %x!!!", cs->hwndParent));
375 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
376 return FALSE;
377 }
378 }
379 else
380 {
381 SetParent(0);
382 if (!cs->hwndParent || (cs->hwndParent == windowDesktop->getWindowHandle())) {
383 owner = NULL;
384 }
385 else
386 {
387 owner = GetWindowFromHandle(cs->hwndParent)->GetTopParent();
388 if(owner == NULL)
389 {
390 dprintf(("HwGetWindowHandleData couldn't find owner window %x!!!", cs->hwndParent));
391 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
392 return FALSE;
393 }
394 }
395 }
396
397 WINPROC_SetProc((HWINDOWPROC *)&win32wndproc, windowClass->getWindowProc(), WINPROC_GetProcType(windowClass->getWindowProc()), WIN_PROC_WINDOW);
398 hInstance = cs->hInstance;
399 dwStyle = cs->style & ~WS_VISIBLE;
400 dwExStyle = cs->dwExStyle;
401
402 hwndLinkAfter = HWND_TOP;
403 if(CONTROLS_IsControl(this, BUTTON_CONTROL) && ((dwStyle & 0x0f) == BS_GROUPBOX))
404 {
405 hwndLinkAfter = HWND_BOTTOM;
406 dwStyle |= WS_CLIPSIBLINGS;
407 }
408 else
409 if(CONTROLS_IsControl(this, STATIC_CONTROL) && !(dwStyle & WS_GROUP)) {
410 dwStyle |= WS_CLIPSIBLINGS;
411 }
412
413 /* Increment class window counter */
414 windowClass->IncreaseWindowCount();
415
416 if (HOOK_IsHooked( WH_CBT ))
417 {
418 CBT_CREATEWNDA cbtc;
419 LRESULT ret;
420
421 cbtc.lpcs = cs;
422 cbtc.hwndInsertAfter = hwndLinkAfter;
423 ret = HOOK_CallHooksA(WH_CBT, HCBT_CREATEWND, getWindowHandle(), (LPARAM)&cbtc);
424 if(ret)
425 {
426 dprintf(("CBT-hook returned 0!!"));
427 SetLastError(ERROR_CAN_NOT_COMPLETE); //todo: wrong error
428 return FALSE;
429 }
430 }
431
432 /* Correct the window style */
433 if (!(cs->style & WS_CHILD))
434 {
435 dwStyle |= WS_CLIPSIBLINGS;
436 if (!(cs->style & WS_POPUP))
437 {
438 dwStyle |= WS_CAPTION;
439 flags |= WIN_NEED_SIZE;
440 }
441 }
442 if (cs->dwExStyle & WS_EX_DLGMODALFRAME) dwStyle &= ~WS_THICKFRAME;
443
444 if (cs->style & WS_HSCROLL)
445 {
446 horzScrollInfo = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
447 horzScrollInfo->MinVal = horzScrollInfo->CurVal = horzScrollInfo->Page = 0;
448 horzScrollInfo->MaxVal = 100;
449 horzScrollInfo->flags = ESB_ENABLE_BOTH;
450 }
451
452 if (cs->style & WS_VSCROLL)
453 {
454 vertScrollInfo = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
455 vertScrollInfo->MinVal = vertScrollInfo->CurVal = vertScrollInfo->Page = 0;
456 vertScrollInfo->MaxVal = 100;
457 vertScrollInfo->flags = ESB_ENABLE_BOTH;
458 }
459
460 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
461 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
462 {
463 GetMinMaxInfo(&maxSize, &maxPos, &minTrack, &maxTrack);
464 if (maxSize.x < cs->cx) cs->cx = maxSize.x;
465 if (maxSize.y < cs->cy) cs->cy = maxSize.y;
466 if (cs->cx < minTrack.x) cs->cx = minTrack.x;
467 if (cs->cy < minTrack.y) cs->cy = minTrack.y;
468 }
469
470 if(cs->style & WS_CHILD)
471 {
472 if(cs->cx < 0) cs->cx = 0;
473 if(cs->cy < 0) cs->cy = 0;
474 }
475 else
476 {
477 if (cs->cx <= 0) cs->cx = 1;
478 if (cs->cy <= 0) cs->cy = 1;
479 }
480
481 if(((dwStyle & 0xC0000000) == WS_OVERLAPPED) && ((dwStyle & WS_CAPTION) == WS_CAPTION) && owner == NULL
482 && dwStyle & WS_SYSMENU)
483 {
484 fTaskList = TRUE;
485 }
486
487 DWORD dwOSWinStyle;
488
489 OSLibWinConvertStyle(dwStyle, dwExStyle, &dwOSWinStyle);
490
491 if(HIWORD(cs->lpszName))
492 {
493 if (!isUnicode)
494 {
495 wndNameLength = strlen(cs->lpszName);
496 windowNameA = (LPSTR)_smalloc(wndNameLength+1);
497 strcpy(windowNameA,cs->lpszName);
498 windowNameW = (LPWSTR)_smalloc((wndNameLength+1)*sizeof(WCHAR));
499 lstrcpyAtoW(windowNameW,windowNameA);
500 windowNameA[wndNameLength] = 0;
501 windowNameW[wndNameLength] = 0;
502 }
503 else
504 {
505 wndNameLength = lstrlenW((LPWSTR)cs->lpszName);
506 windowNameA = (LPSTR)_smalloc(wndNameLength+1);
507 lstrcpyWtoA(windowNameA,(LPWSTR)cs->lpszName);
508 windowNameW = (LPWSTR)_smalloc((wndNameLength+1)*sizeof(WCHAR));
509 lstrcpyW(windowNameW,(LPWSTR)cs->lpszName);
510 windowNameA[wndNameLength] = 0;
511 windowNameW[wndNameLength] = 0;
512 }
513 }
514
515 //copy pointer of CREATESTRUCT for usage in MsgCreate method
516 tmpcs = cs;
517
518 //Store our window object pointer in thread local memory, so PMWINDOW.CPP can retrieve it
519 THDB *thdb = GetThreadTHDB();
520
521 if(thdb == NULL) {
522 dprintf(("Window creation failed - thdb == NULL")); //this is VERY bad
523 ExitProcess(666);
524 return FALSE;
525 }
526
527 thdb->newWindow = (ULONG)this;
528
529 OS2Hwnd = OSLibWinCreateWindow((getParent()) ? getParent()->getOS2WindowHandle() : OSLIB_HWND_DESKTOP,
530 dwOSWinStyle,(char *)windowNameA,
531 (owner) ? owner->getOS2WindowHandle() : OSLIB_HWND_DESKTOP,
532 (hwndLinkAfter == HWND_BOTTOM) ? TRUE : FALSE,
533 &OS2HwndFrame, 0, fTaskList, 0, windowClass->getStyle() & CS_SAVEBITS);
534 if(OS2Hwnd == 0) {
535 dprintf(("Window creation failed!!"));
536 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
537 return FALSE;
538 }
539
540 SetLastError(0);
541 return TRUE;
542}
543#else
544BOOL Win32BaseWindow::CreateWindowExA(CREATESTRUCTA *cs, ATOM classAtom)
545{
546 char buffer[256];
547 POINT maxSize, maxPos, minTrack, maxTrack;
548 BOOL xDefault = FALSE,cxDefault = FALSE;
549
550#ifdef DEBUG
551 PrintWindowStyle(cs->style, cs->dwExStyle);
552#endif
553
554 sw = SW_SHOW;
555 SetLastError(0);
556
557 /* Find the parent window */
558 if (cs->hwndParent)
559 {
560 Win32BaseWindow *window = GetWindowFromHandle(cs->hwndParent);
561 if(!window) {
562 dprintf(("Bad parent %04x\n", cs->hwndParent ));
563 SetLastError(ERROR_INVALID_PARAMETER);
564 return FALSE;
565 }
566 /* Make sure parent is valid */
567 if (!window->IsWindow() )
568 {
569 dprintf(("Bad parent %04x\n", cs->hwndParent ));
570 SetLastError(ERROR_INVALID_PARAMETER);
571 return FALSE;
572 }
573 }
574 else
575 if ((cs->style & WS_CHILD) && !(cs->style & WS_POPUP)) {
576 dprintf(("No parent for child window\n" ));
577 SetLastError(ERROR_INVALID_PARAMETER);
578 return FALSE; /* WS_CHILD needs a parent, but WS_POPUP doesn't */
579 }
580
581 /* Find the window class */
582 windowClass = Win32WndClass::FindClass(cs->hInstance, (LPSTR)classAtom);
583 if (!windowClass)
584 {
585 GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) );
586 dprintf(("Bad class '%s'\n", buffer ));
587 SetLastError(ERROR_INVALID_PARAMETER);
588 return 0;
589 }
590#ifdef DEBUG
591 if(HIWORD(cs->lpszClass))
592 {
593 char *astring;
594
595 if(isUnicode) astring = UnicodeToAsciiString((LPWSTR)cs->lpszClass);
596 else astring = (char *)cs->lpszClass;
597
598 dprintf(("Window class %s", astring));
599 if(isUnicode) FreeAsciiString(astring);
600 }
601 else dprintf(("Window class %x", cs->lpszClass));
602#endif
603
604 /* Fix the lpszClass field: from existing programs, it seems ok to call a CreateWindowXXX
605 * with an atom as the class name, put some programs expect to have a *REAL* string in
606 * lpszClass when the CREATESTRUCT is sent with WM_CREATE
607 */
608 if (!HIWORD(cs->lpszClass) ) {
609 if (isUnicode) {
610 GlobalGetAtomNameW( classAtom, (LPWSTR)buffer, sizeof(buffer) );
611 }
612 else {
613 GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) );
614 }
615 cs->lpszClass = buffer;
616 }
617
618 /* Fix the coordinates */
619 if ((cs->x == CW_USEDEFAULT) || (cs->x == CW_USEDEFAULT16))
620 {
621 /* Never believe Microsoft's documentation... CreateWindowEx doc says
622 * that if an overlapped window is created with WS_VISIBLE style bit
623 * set and the x parameter is set to CW_USEDEFAULT, the system ignores
624 * the y parameter. However, disassembling NT implementation (WIN32K.SYS)
625 * reveals that
626 *
627 * 1) not only if checks for CW_USEDEFAULT but also for CW_USEDEFAULT16
628 * 2) it does not ignore the y parameter as the docs claim; instead, it
629 * uses it as second parameter to ShowWindow() unless y is either
630 * CW_USEDEFAULT or CW_USEDEFAULT16.
631 *
632 * The fact that we didn't do 2) caused bogus windows pop up when wine
633 * was running apps that were using this obscure feature. Example -
634 * calc.exe that comes with Win98 (only Win98, it's different from
635 * the one that comes with Win95 and NT)
636 */
637 if ((cs->y != CW_USEDEFAULT) && (cs->y != CW_USEDEFAULT16)) sw = cs->y;
638
639 /* We have saved cs->y, now we can trash it */
640 cs->x = 0;
641 cs->y = 0;
642 xDefault = TRUE;
643 }
644 if ((cs->cx == CW_USEDEFAULT) || (cs->cx == CW_USEDEFAULT16))
645 {
646 cs->cx = 600; /* FIXME */
647 cs->cy = 400;
648 cxDefault = TRUE;
649 }
650
651 if (cs->x < 0) cs->x = 0;
652 if (cs->y < 0) cs->y = 0;
653
654 //Allocate window words
655 nrUserWindowLong = windowClass->getExtraWndWords();
656 if(nrUserWindowLong) {
657 userWindowLong = (ULONG *)_smalloc(nrUserWindowLong);
658 memset(userWindowLong, 0, nrUserWindowLong);
659 }
660
661 if ((cs->style & WS_CHILD) && cs->hwndParent)
662 {
663 SetParent(cs->hwndParent);
664 owner = GetWindowFromHandle(cs->hwndParent);
665 if(owner == NULL)
666 {
667 dprintf(("HwGetWindowHandleData couldn't find owner window %x!!!", cs->hwndParent));
668 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
669 return FALSE;
670 }
671 }
672 else
673 {
674 SetParent(0);
675 if (!cs->hwndParent || (cs->hwndParent == windowDesktop->getWindowHandle())) {
676 owner = NULL;
677 }
678 else
679 {
680 owner = GetWindowFromHandle(cs->hwndParent)->GetTopParent();
681 if(owner == NULL)
682 {
683 dprintf(("HwGetWindowHandleData couldn't find owner window %x!!!", cs->hwndParent));
684 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
685 return FALSE;
686 }
687 }
688 }
689
690 WINPROC_SetProc((HWINDOWPROC *)&win32wndproc, windowClass->getWindowProc(), WINPROC_GetProcType(windowClass->getWindowProc()), WIN_PROC_WINDOW);
691 hInstance = cs->hInstance;
692 dwStyle = cs->style & ~WS_VISIBLE;
693 dwExStyle = cs->dwExStyle;
694
695 hwndLinkAfter = HWND_TOP;
696 if(CONTROLS_IsControl(this, BUTTON_CONTROL) && ((dwStyle & 0x0f) == BS_GROUPBOX))
697 {
698 hwndLinkAfter = HWND_BOTTOM;
699 dwStyle |= WS_CLIPSIBLINGS;
700 }
701 else
702 if(CONTROLS_IsControl(this, STATIC_CONTROL) && !(dwStyle & WS_GROUP)) {
703 dwStyle |= WS_CLIPSIBLINGS;
704 }
705
706 /* Increment class window counter */
707 windowClass->IncreaseWindowCount();
708
709 if (HOOK_IsHooked( WH_CBT ))
710 {
711 CBT_CREATEWNDA cbtc;
712 LRESULT ret;
713
714 cbtc.lpcs = cs;
715 cbtc.hwndInsertAfter = hwndLinkAfter;
716 ret = HOOK_CallHooksA(WH_CBT, HCBT_CREATEWND, getWindowHandle(), (LPARAM)&cbtc);
717 if(ret)
718 {
719 dprintf(("CBT-hook returned 0!!"));
720 SetLastError(ERROR_CAN_NOT_COMPLETE); //todo: wrong error
721 return FALSE;
722 }
723 }
724
725 /* Correct the window style */
726 if (!(cs->style & WS_CHILD))
727 {
728 dwStyle |= WS_CLIPSIBLINGS;
729 if (!(cs->style & WS_POPUP))
730 {
731 dwStyle |= WS_CAPTION;
732 flags |= WIN_NEED_SIZE;
733 }
734 }
735 if (cs->dwExStyle & WS_EX_DLGMODALFRAME) dwStyle &= ~WS_THICKFRAME;
736
737 if (cs->style & WS_HSCROLL)
738 {
739 horzScrollInfo = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
740 horzScrollInfo->MinVal = horzScrollInfo->CurVal = horzScrollInfo->Page = 0;
741 horzScrollInfo->MaxVal = 100;
742 horzScrollInfo->flags = ESB_ENABLE_BOTH;
743 }
744
745 if (cs->style & WS_VSCROLL)
746 {
747 vertScrollInfo = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
748 vertScrollInfo->MinVal = vertScrollInfo->CurVal = vertScrollInfo->Page = 0;
749 vertScrollInfo->MaxVal = 100;
750 vertScrollInfo->flags = ESB_ENABLE_BOTH;
751 }
752
753 if(HIWORD(cs->lpszName))
754 {
755 if (!isUnicode)
756 {
757 wndNameLength = strlen(cs->lpszName);
758 windowNameA = (LPSTR)_smalloc(wndNameLength+1);
759 strcpy(windowNameA,cs->lpszName);
760 windowNameW = (LPWSTR)_smalloc((wndNameLength+1)*sizeof(WCHAR));
761 lstrcpyAtoW(windowNameW,windowNameA);
762 windowNameA[wndNameLength] = 0;
763 windowNameW[wndNameLength] = 0;
764 }
765 else
766 {
767 wndNameLength = lstrlenW((LPWSTR)cs->lpszName);
768 windowNameA = (LPSTR)_smalloc(wndNameLength+1);
769 lstrcpyWtoA(windowNameA,(LPWSTR)cs->lpszName);
770 windowNameW = (LPWSTR)_smalloc((wndNameLength+1)*sizeof(WCHAR));
771 lstrcpyW(windowNameW,(LPWSTR)cs->lpszName);
772 windowNameA[wndNameLength] = 0;
773 windowNameW[wndNameLength] = 0;
774 }
775 }
776
777 //copy pointer of CREATESTRUCT for usage in MsgCreate method
778 tmpcs = cs;
779
780 //Store our window object pointer in thread local memory, so PMWINDOW.CPP can retrieve it
781 THDB *thdb = GetThreadTHDB();
782
783 if(thdb == NULL) {
784 dprintf(("Window creation failed - thdb == NULL")); //this is VERY bad
785 ExitProcess(666);
786 return FALSE;
787 }
788
789 thdb->newWindow = (ULONG)this;
790
791 DWORD dwOSWinStyle;
792
793 OSLibWinConvertStyle(dwStyle,dwExStyle,&dwOSWinStyle);
794 if (((dwStyle & (WS_CAPTION | WS_SYSMENU | 0xC0000000)) == (WS_CAPTION | WS_SYSMENU))) fTaskList = TRUE;
795
796 OS2Hwnd = OSLibWinCreateWindow((getParent()) ? getParent()->getOS2WindowHandle() : OSLIB_HWND_DESKTOP,
797 dwOSWinStyle,(char *)windowNameA,
798 (owner) ? owner->getOS2WindowHandle() : OSLIB_HWND_DESKTOP,
799 (hwndLinkAfter == HWND_BOTTOM) ? TRUE : FALSE,
800 &OS2HwndFrame, 0, fTaskList,xDefault | cxDefault,windowClass->getStyle() & CS_SAVEBITS);
801 if(OS2Hwnd == 0) {
802 dprintf(("Window creation failed!!"));
803 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
804 return FALSE;
805 }
806
807 //adjust CW_USEDEFAULT position
808 if (xDefault | cxDefault)
809 {
810 RECT rect;
811
812 OSLibWinQueryWindowRect(OS2HwndFrame,&rect,RELATIVE_TO_SCREEN);
813 if (getParent()) mapWin32Rect(OSLIB_HWND_DESKTOP,getParent()->getOS2FrameWindowHandle(),&rect);
814 if (xDefault)
815 {
816 cs->x = rect.left;
817 cs->y = rect.top;
818 }
819 if (cxDefault)
820 {
821 cs->cx = rect.right-rect.left;
822 cs->cy = rect.bottom-rect.top;
823 }
824 }
825
826 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
827 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
828 {
829 GetMinMaxInfo(&maxSize, &maxPos, &minTrack, &maxTrack);
830 if (maxSize.x < cs->cx) cs->cx = maxSize.x;
831 if (maxSize.y < cs->cy) cs->cy = maxSize.y;
832 if (cs->cx < minTrack.x) cs->cx = minTrack.x;
833 if (cs->cy < minTrack.y) cs->cy = minTrack.y;
834 }
835
836 if(cs->style & WS_CHILD)
837 {
838 if(cs->cx < 0) cs->cx = 0;
839 if(cs->cy < 0) cs->cy = 0;
840 }
841 else
842 {
843 if (cs->cx <= 0) cs->cx = 1;
844 if (cs->cy <= 0) cs->cy = 1;
845 }
846
847 SetLastError(0);
848 return TRUE;
849}
850#endif
851//******************************************************************************
852//******************************************************************************
853BOOL Win32BaseWindow::MsgCreate(HWND hwndFrame, HWND hwndClient)
854{
855 POINT maxPos;
856 CREATESTRUCTA *cs = tmpcs; //pointer to CREATESTRUCT used in CreateWindowExA method
857
858 OS2Hwnd = hwndClient;
859 OS2HwndFrame = hwndFrame;
860
861 fNoSizeMsg = TRUE;
862
863 if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, (ULONG)this) == FALSE) {
864 dprintf(("WM_CREATE: WinSetWindowULong %X failed!!", OS2Hwnd));
865 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
866 return FALSE;
867 }
868 if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, WIN32PM_MAGIC) == FALSE) {
869 dprintf(("WM_CREATE: WinSetWindowULong2 %X failed!!", OS2Hwnd));
870 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
871 return FALSE;
872 }
873
874 OSLibWinSetOwner(OS2Hwnd, OS2HwndFrame);
875
876 fakeWinBase.hwndThis = OS2Hwnd;
877 fakeWinBase.pWindowClass = windowClass;
878
879 //Set icon from class
880 if(windowClass->getIcon())
881 SetIcon(windowClass->getIcon());
882 /* Get class or window DC if needed */
883 if(windowClass->getStyle() & CS_OWNDC) {
884 dprintf(("Class with CS_OWNDC style"));
885 ownDC = GetDC(getWindowHandle()); //TODO: or GetWindowDC???
886 }
887 else
888 if (windowClass->getStyle() & CS_PARENTDC) {
889 dprintf(("WARNING: Class with CS_PARENTDC style!"));
890 fParentDC = TRUE;
891 ownDC = 0;
892 }
893 else
894 if (windowClass->getStyle() & CS_CLASSDC) {
895 dprintf(("WARNING: Class with CS_CLASSDC style!"));
896 ownDC = 0;
897 }
898 /* Set the window menu */
899 if ((dwStyle & (WS_CAPTION | WS_CHILD)) == WS_CAPTION )
900 {
901 if (cs->hMenu) {
902 ::SetMenu(getWindowHandle(), cs->hMenu);
903 }
904 else {
905 if (windowClass->getMenuNameA()) {
906 cs->hMenu = LoadMenuA(cs->hInstance, windowClass->getMenuNameA());
907 if (cs->hMenu) ::SetMenu(getWindowHandle(), cs->hMenu );
908 }
909 }
910 }
911 else
912 {
913 setWindowId((DWORD)cs->hMenu);
914 }
915 hSysMenu = (dwStyle & WS_SYSMENU) ? MENU_GetSysMenu(Win32Hwnd,0):0;
916
917 // Subclass frame
918 pOldFrameProc = FrameSubclassFrameWindow(this);
919
920 //preset rects
921 rectWindow.left = cs->x;
922 rectWindow.right = cs->x+cs->cx;
923 rectWindow.top = cs->y;
924 rectWindow.bottom = cs->y+cs->cy;
925 rectClient = rectWindow; //dummy client rect
926 OffsetRect(&rectClient, -rectClient.left, -rectClient.top);
927
928 if (getParent()) mapWin32Rect(getParent()->getOS2WindowHandle(),OSLIB_HWND_DESKTOP,&rectWindow);
929 /* Send the WM_CREATE message
930 * Perhaps we shouldn't allow width/height changes as well.
931 * See p327 in "Internals".
932 */
933 maxPos.x = rectWindow.left; maxPos.y = rectWindow.top;
934
935 //Note: Solitaire crashes when receiving WM_SIZE messages before WM_CREATE
936 //fNoSizeMsg = FALSE;
937 fCreated = TRUE;
938
939 if (SendInternalMessageA(WM_NCCREATE,0,(LPARAM)cs))
940 {
941 RECT tmpRect;
942
943 //update rect
944 rectWindow.left = cs->x;
945 rectWindow.right = cs->x+cs->cx;
946 rectWindow.top = cs->y;
947 rectWindow.bottom = cs->y+cs->cy;
948 tmpRect = rectWindow;
949 if (getParent()) mapWin32Rect(getParent()->getOS2WindowHandle(),OSLIB_HWND_DESKTOP,&rectWindow);
950 OffsetRect(&rectWindow, maxPos.x - rectWindow.left, maxPos.y - rectWindow.top);
951
952 rectClient = rectWindow;
953 OffsetRect(&rectClient, -rectClient.left, -rectClient.top);
954
955 //set the window size and update the client
956 SetWindowPos(hwndLinkAfter, tmpRect.left, tmpRect.top, tmpRect.right-tmpRect.left, tmpRect.bottom-tmpRect.top,SWP_NOACTIVATE | SWP_NOREDRAW | SWP_FRAMECHANGED);
957 fNoSizeMsg = FALSE;
958 if (cs->style & WS_VISIBLE) dwStyle |= WS_VISIBLE; //program could change position in WM_CREATE
959 if( (SendInternalMessageA(WM_CREATE, 0, (LPARAM)cs )) != -1 )
960 {
961 if(!(flags & WIN_NEED_SIZE))
962 {
963 SendInternalMessageA(WM_SIZE, SIZE_RESTORED,
964 MAKELONG(rectClient.right-rectClient.left,
965 rectClient.bottom-rectClient.top));
966
967 SendInternalMessageA(WM_MOVE,0,MAKELONG(rectClient.left,rectClient.top));
968 }
969
970 if( (getStyle() & WS_CHILD) && !(getExStyle() & WS_EX_NOPARENTNOTIFY) )
971 {
972 /* Notify the parent window only */
973 SendInternalMessageA(WM_PARENTNOTIFY, MAKEWPARAM(WM_CREATE, getWindowId()), (LPARAM)getWindowHandle());
974 if(!::IsWindow(getWindowHandle()))
975 {
976 dprintf(("Createwindow: WM_PARENTNOTIFY destroyed window"));
977 goto end;
978 }
979 }
980
981 //CB: timew32.exe, blockcad.exe -> children not shown!!!
982 if (cs->style & WS_VISIBLE) ShowWindow(sw);
983
984 /* Call WH_SHELL hook */
985 if (!(getStyle() & WS_CHILD) && !owner)
986 HOOK_CallHooksA(WH_SHELL, HSHELL_WINDOWCREATED, getWindowHandle(), 0 );
987
988 SetLastError(0);
989 return TRUE;
990 }
991 }
992 dprintf(("Window creation FAILED (NCCREATE cancelled creation)"));
993 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
994end:
995 return FALSE;
996}
997//******************************************************************************
998//******************************************************************************
999ULONG Win32BaseWindow::MsgQuit()
1000{
1001 return SendInternalMessageA(WM_QUIT, 0, 0);
1002}
1003//******************************************************************************
1004//******************************************************************************
1005ULONG Win32BaseWindow::MsgClose()
1006{
1007 return SendInternalMessageA(WM_CLOSE,0,0);
1008}
1009//******************************************************************************
1010//******************************************************************************
1011ULONG Win32BaseWindow::MsgDestroy()
1012{
1013 ULONG rc;
1014 Win32BaseWindow *child;
1015 HWND hwnd = getWindowHandle();
1016
1017 fIsDestroyed = TRUE;
1018
1019 if(fDestroyWindowCalled == FALSE)
1020 {//this window was destroyed because DestroyWindow was called for it's parent
1021 //so: send a WM_PARENTNOTIFY now as that hasn't happened yet
1022 if((getStyle() & WS_CHILD) && !(getExStyle() & WS_EX_NOPARENTNOTIFY))
1023 {
1024 if(getParent())
1025 {
1026 /* Notify the parent window only */
1027 getParent()->SendMessageA(WM_PARENTNOTIFY, MAKEWPARAM(WM_DESTROY, getWindowId()), (LPARAM)getWindowHandle());
1028 }
1029 else DebugInt3();
1030 }
1031 }
1032 SendInternalMessageA(WM_DESTROY, 0, 0);
1033 if(::IsWindow(hwnd) == FALSE) {
1034 //object already destroyed, so return immediately
1035 return 1;
1036 }
1037 SendInternalMessageA(WM_NCDESTROY, 0, 0);
1038
1039 TIMER_KillTimerFromWindow(OS2Hwnd);
1040
1041 if(getFirstChild() == NULL) {
1042 delete this;
1043 }
1044 return 1;
1045}
1046//******************************************************************************
1047//******************************************************************************
1048ULONG Win32BaseWindow::MsgEnable(BOOL fEnable)
1049{
1050 if(fEnable) {
1051 dwStyle &= ~WS_DISABLED;
1052 }
1053 else dwStyle |= WS_DISABLED;
1054
1055 return SendInternalMessageA(WM_ENABLE, fEnable, 0);
1056}
1057//******************************************************************************
1058//TODO: SW_PARENTCLOSING/OPENING flag (lParam)
1059//******************************************************************************
1060ULONG Win32BaseWindow::MsgShow(BOOL fShow)
1061{
1062 if(fNoSizeMsg) {
1063 return 1;
1064 }
1065
1066 if(fShow) {
1067 setStyle(getStyle() | WS_VISIBLE);
1068 }
1069 else setStyle(getStyle() & ~WS_VISIBLE);
1070
1071 return SendInternalMessageA(WM_SHOWWINDOW, fShow, 0);
1072}
1073//******************************************************************************
1074//******************************************************************************
1075ULONG Win32BaseWindow::MsgPosChanging(LPARAM lp)
1076{
1077 //SvL: Notes crashes when switching views (calls DestroyWindow -> PM sends
1078 // a WM_WINDOWPOSCHANGED msg -> crash)
1079 if(fNoSizeMsg || fDestroyWindowCalled)
1080 return 0;
1081
1082 return SendInternalMessageA(WM_WINDOWPOSCHANGING, 0, lp);
1083}
1084//******************************************************************************
1085//******************************************************************************
1086ULONG Win32BaseWindow::MsgPosChanged(LPARAM lp)
1087{
1088 //SvL: Notes crashes when switching views (calls DestroyWindow -> PM sends
1089 // a WM_WINDOWPOSCHANGED msg -> crash)
1090 if(fNoSizeMsg || fDestroyWindowCalled)
1091 return 1;
1092
1093 return SendInternalMessageA(WM_WINDOWPOSCHANGED, 0, lp);
1094}
1095//******************************************************************************
1096//******************************************************************************
1097#if 0
1098ULONG Win32BaseWindow::MsgMinMax()
1099{
1100
1101}
1102#endif
1103//******************************************************************************
1104//******************************************************************************
1105ULONG Win32BaseWindow::MsgScroll(ULONG msg, ULONG scrollCode, ULONG scrollPos)
1106{
1107 //According to the SDK docs, the scrollbar handle (lParam) is 0 when the standard
1108 //window scrollbars send these messages
1109 return SendInternalMessageA(msg, MAKELONG(scrollCode, scrollPos), 0);
1110}
1111//******************************************************************************
1112//******************************************************************************
1113ULONG Win32BaseWindow::MsgHitTest(ULONG x, ULONG y)
1114{
1115 lastHitTestVal = SendInternalMessageA(WM_NCHITTEST, 0, MAKELONG((USHORT)x, (USHORT)y));
1116 dprintf2(("MsgHitTest (%d,%d) (%d,%d) (%d,%d) returned %x", x, y, rectWindow.left, rectWindow.right, rectWindow.top, rectWindow.bottom, lastHitTestVal));
1117 return lastHitTestVal;
1118}
1119//******************************************************************************
1120//******************************************************************************
1121ULONG Win32BaseWindow::MsgActivate(BOOL fActivate, BOOL fMinimized, HWND hwnd, HWND hwndOS2Win)
1122{
1123 ULONG rc, procidhwnd = -1, threadidhwnd = 0;
1124
1125
1126 //According to SDK docs, if app returns FALSE & window is being deactivated,
1127 //default processing is cancelled
1128 //TODO: According to Wine we should proceed anyway if window is sysmodal
1129#if 0
1130 if(SendInternalMessageA(WM_NCACTIVATE, fActivate, 0) == FALSE && !fActivate)
1131 {
1132 return 0;
1133 }
1134#endif
1135 /* child windows get WM_CHILDACTIVATE message */
1136 if((getStyle() & (WS_CHILD | WS_POPUP)) == WS_CHILD )
1137 {
1138 SendInternalMessageA(WM_CHILDACTIVATE, 0, 0L);
1139 return 0;
1140 }
1141
1142 rc = SendInternalMessageA(WM_ACTIVATE, MAKELONG((fActivate) ? WA_ACTIVE : WA_INACTIVE, fMinimized), hwnd);
1143
1144 if(hwndOS2Win) {
1145 threadidhwnd = O32_GetWindowThreadProcessId(hwndOS2Win, &procidhwnd);
1146 }
1147
1148 if(fActivate) {
1149 SendInternalMessageA(WM_ACTIVATEAPP, 1, dwThreadId); //activate; specify window thread id
1150 }
1151 else SendInternalMessageA(WM_ACTIVATEAPP, 0, threadidhwnd); //deactivate; specify thread id of other process
1152 return rc;
1153}
1154//******************************************************************************
1155//TODO: Is this correct and complete?
1156//Add print screen, break & numlock
1157//******************************************************************************
1158void Win32BaseWindow::setExtendedKey(ULONG virtualkey, ULONG *lParam)
1159{
1160 switch(virtualkey) {
1161 case VK_DOWN:
1162 case VK_UP:
1163 case VK_PRIOR:
1164 case VK_NEXT:
1165 case VK_END:
1166 case VK_DIVIDE:
1167 case VK_DELETE:
1168 case VK_EXECUTE: //Numeric enter key?
1169 case VK_HOME:
1170 case VK_INSERT:
1171 case VK_RCONTROL:
1172 case VK_RMENU: //is this the right alt???
1173 *lParam = *lParam | (1<<24);
1174 }
1175}
1176//******************************************************************************
1177//******************************************************************************
1178ULONG Win32BaseWindow::DispatchMsgA(MSG *msg)
1179{
1180 return SendInternalMessageA(msg->message, msg->wParam, msg->lParam);
1181}
1182//******************************************************************************
1183//******************************************************************************
1184ULONG Win32BaseWindow::DispatchMsgW(MSG *msg)
1185{
1186 return SendInternalMessageW(msg->message, msg->wParam, msg->lParam);
1187}
1188//******************************************************************************
1189//******************************************************************************
1190ULONG Win32BaseWindow::MsgSetFocus(HWND hwnd)
1191{
1192 return SendInternalMessageA(WM_SETFOCUS, hwnd, 0);
1193}
1194//******************************************************************************
1195//******************************************************************************
1196ULONG Win32BaseWindow::MsgKillFocus(HWND hwnd)
1197{
1198 return SendInternalMessageA(WM_KILLFOCUS, hwnd, 0);
1199}
1200//******************************************************************************
1201//******************************************************************************
1202ULONG Win32BaseWindow::MsgButton(MSG *msg)
1203{
1204 BOOL fClick = FALSE;
1205
1206// dprintf(("MsgButton at (%d,%d)", msg->pt.x, msg->pt.y));
1207 switch(msg->message) {
1208 case WM_LBUTTONDBLCLK:
1209 case WM_RBUTTONDBLCLK:
1210 case WM_MBUTTONDBLCLK:
1211 case WM_NCLBUTTONDBLCLK:
1212 case WM_NCRBUTTONDBLCLK:
1213 case WM_NCMBUTTONDBLCLK:
1214 if (!(windowClass && windowClass->getClassLongA(GCL_STYLE) & CS_DBLCLKS) && (msg->message != WM_NCLBUTTONDBLCLK))
1215 {
1216 msg->message = msg->message - (WM_LBUTTONDBLCLK - WM_LBUTTONDOWN); //dblclick -> down
1217 MsgButton(msg);
1218 msg->message++; //button-up
1219 return MsgButton(msg);
1220 }
1221 break;
1222 case WM_LBUTTONDOWN:
1223 case WM_RBUTTONDOWN:
1224 case WM_MBUTTONDOWN:
1225 case WM_NCLBUTTONDOWN:
1226 case WM_NCRBUTTONDOWN:
1227 case WM_NCMBUTTONDOWN:
1228 fClick = TRUE;
1229 break;
1230 }
1231
1232 if(ISMOUSE_CAPTURED())
1233 {
1234 if(DInputMouseHandler(getWindowHandle(), MOUSEMSG_BUTTON, msg->pt.x, msg->pt.y))
1235 return 0;
1236 }
1237
1238 if(fClick)
1239 {
1240 HWND hwndTop;
1241
1242 /* Activate the window if needed */
1243 hwndTop = (GetTopParent()) ? GetTopParent()->getWindowHandle() : 0;
1244
1245 HWND hwndActive = GetActiveWindow();
1246 if (hwndTop && (getWindowHandle() != hwndActive))
1247 {
1248 LONG ret = SendInternalMessageA(WM_MOUSEACTIVATE, hwndTop,
1249 MAKELONG( lastHitTestVal, msg->message) );
1250
1251#if 0
1252 if ((ret == MA_ACTIVATEANDEAT) || (ret == MA_NOACTIVATEANDEAT))
1253 eatMsg = TRUE;
1254#endif
1255 if(((ret == MA_ACTIVATE) || (ret == MA_ACTIVATEANDEAT))
1256 && (hwndTop != GetForegroundWindow()) )
1257 {
1258 ::SetActiveWindow(hwndTop);
1259 }
1260 }
1261 }
1262
1263 SendInternalMessageA(WM_SETCURSOR, getWindowHandle(), MAKELONG(lastHitTestVal, msg->message));
1264
1265 return SendInternalMessageA(msg->message, msg->wParam, msg->lParam);
1266}
1267//******************************************************************************
1268//******************************************************************************
1269ULONG Win32BaseWindow::MsgPaint(ULONG tmp1, BOOL select)
1270{
1271 if (select && isIcon)
1272 return SendInternalMessageA(WM_PAINTICON, 0, 0);
1273 else
1274 return SendInternalMessageA(WM_PAINT, 0, 0);
1275}
1276//******************************************************************************
1277//TODO: Is the clipper region of the window DC equal to the invalidated rectangle?
1278// (or are we simply erasing too much here)
1279//******************************************************************************
1280ULONG Win32BaseWindow::MsgEraseBackGround(HDC hdc)
1281{
1282 ULONG rc;
1283 HDC hdcErase = hdc;
1284
1285 if (hdcErase == 0)
1286 hdcErase = O32_GetDC(OS2Hwnd);
1287
1288 if(isIcon)
1289 rc = SendInternalMessageA(WM_ICONERASEBKGND, hdcErase, 0);
1290 else
1291 rc = SendInternalMessageA(WM_ERASEBKGND, hdcErase, 0);
1292 if (hdc == 0)
1293 O32_ReleaseDC(OS2Hwnd, hdcErase);
1294 return (rc);
1295}
1296//******************************************************************************
1297//******************************************************************************
1298ULONG Win32BaseWindow::MsgMouseMove(MSG *msg)
1299{
1300 if(ISMOUSE_CAPTURED()) {
1301 if(DInputMouseHandler(getWindowHandle(), MOUSEMSG_MOVE, msg->pt.x, msg->pt.y))
1302 return 0;
1303 }
1304
1305 //TODO: hiword should be 0 if window enters menu mode (SDK docs)
1306 SendInternalMessageA(WM_SETCURSOR, Win32Hwnd, MAKELONG(lastHitTestVal, msg->message));
1307
1308 //translated message == WM_(NC)MOUSEMOVE
1309 return SendInternalMessageA(msg->message, msg->wParam, msg->lParam);
1310}
1311//******************************************************************************
1312//******************************************************************************
1313ULONG Win32BaseWindow::MsgChar(MSG *msg)
1314{
1315 if(ISKDB_CAPTURED())
1316 {
1317 DInputKeyBoardHandler(msg);
1318 }
1319 return DispatchMsgA(msg);
1320}
1321//******************************************************************************
1322//******************************************************************************
1323ULONG Win32BaseWindow::MsgNCPaint()
1324{
1325 RECT rect;
1326
1327 if (GetOS2UpdateRect(OS2HwndFrame,&rect))
1328 {
1329 HRGN hrgn;
1330 ULONG rc;
1331 RECT client = rectClient;
1332
1333//// mapWin32Rect(getParent() ? getParent()->getOS2WindowHandle():OSLIB_HWND_DESKTOP,OS2HwndFrame,&client);
1334 if ((rect.left >= client.left) && (rect.left < client.right) &&
1335 (rect.right >= client.left) && (rect.right < client.right) &&
1336 (rect.top >= client.top) && (rect.top < client.bottom) &&
1337 (rect.bottom >= client.top) && (rect.bottom < client.bottom))
1338 return 0;
1339
1340 hrgn = CreateRectRgnIndirect(&rect);
1341 if (!hrgn) return 0;
1342 rc = SendInternalMessageA(WM_NCPAINT,hrgn,0);
1343 DeleteObject(hrgn);
1344
1345 return rc;
1346 }
1347 else return 0;
1348}
1349//******************************************************************************
1350//Called when either the frame's size or position has changed (lpWndPos != NULL)
1351//or when the frame layout has changed (i.e. scrollbars added/removed) (lpWndPos == NULL)
1352//******************************************************************************
1353ULONG Win32BaseWindow::MsgFormatFrame(WINDOWPOS *lpWndPos)
1354{
1355 RECT oldWindowRect = rectWindow, client = rectClient, newWindowRect;
1356 WINDOWPOS wndPos;
1357 ULONG rc;
1358
1359 if(lpWndPos)
1360 {
1361 POINT point;
1362
1363 //set new window rectangle
1364 point.x = lpWndPos->x;
1365 point.y = lpWndPos->y;
1366 if (getParent()) ClientToScreen(getParent()->getWindowHandle(),&point);
1367
1368 setWindowRect(point.x,point.y,point.x+lpWndPos->cx,point.y+lpWndPos->cy);
1369 newWindowRect = rectWindow;
1370 }
1371 else {
1372 wndPos.hwnd = getWindowHandle();
1373 wndPos.hwndInsertAfter = 0;
1374 newWindowRect= rectWindow;
1375 if (getParent()) {
1376 mapWin32Rect(OSLIB_HWND_DESKTOP,getParent()->getOS2WindowHandle(),&newWindowRect);
1377 }
1378 wndPos.x = newWindowRect.left;
1379 wndPos.y = newWindowRect.top;
1380 wndPos.cx = newWindowRect.right - newWindowRect.left;
1381 wndPos.cy = newWindowRect.bottom - newWindowRect.top;
1382 wndPos.flags = SWP_FRAMECHANGED;
1383 lpWndPos = &wndPos;
1384
1385 if (getParent()) {
1386 newWindowRect= rectWindow; //reset; was modified
1387 }
1388 }
1389
1390 rc = SendNCCalcSize(TRUE, &newWindowRect, &oldWindowRect, &client, lpWndPos, &rectClient);
1391
1392 dprintf(("MsgFormatFrame: old client rect (%d,%d)(%d,%d), new client (%d,%d)(%d,%d)", client.left, client.top, client.right, client.bottom, rectClient.left, rectClient.top, rectClient.right, rectClient.bottom));
1393 return rc;
1394}
1395//******************************************************************************
1396//******************************************************************************
1397ULONG Win32BaseWindow::MsgSetText(LPSTR lpsz, LONG cch)
1398{
1399 return SendInternalMessageA(WM_SETTEXT, 0, (LPARAM)lpsz);
1400}
1401//******************************************************************************
1402//******************************************************************************
1403ULONG Win32BaseWindow::MsgGetTextLength()
1404{
1405 return SendInternalMessageA(WM_GETTEXTLENGTH, 0, 0);
1406}
1407//******************************************************************************
1408//******************************************************************************
1409void Win32BaseWindow::MsgGetText(char *wndtext, ULONG textlength)
1410{
1411 SendInternalMessageA(WM_GETTEXT, textlength, (LPARAM)wndtext);
1412}
1413//******************************************************************************
1414//******************************************************************************
1415BOOL Win32BaseWindow::isMDIClient()
1416{
1417 return FALSE;
1418}
1419//******************************************************************************
1420//******************************************************************************
1421BOOL Win32BaseWindow::isMDIChild()
1422{
1423 return FALSE;
1424}
1425//******************************************************************************
1426//TODO: Not complete
1427//******************************************************************************
1428BOOL Win32BaseWindow::isFrameWindow()
1429{
1430// if(isMDIChild() || IsDialog() || (getParent() == NULL || getParent() == windowDesktop) && ((dwStyle & WS_CAPTION) == WS_CAPTION))
1431 if((dwStyle & WS_CAPTION) == WS_CAPTION || dwStyle & (WS_VSCROLL|WS_HSCROLL))
1432 return TRUE;
1433
1434 return FALSE;
1435}
1436//******************************************************************************
1437//******************************************************************************
1438SCROLLBAR_INFO *Win32BaseWindow::getScrollInfo(int nBar)
1439{
1440 switch(nBar)
1441 {
1442 case SB_HORZ:
1443 if (!horzScrollInfo)
1444 {
1445 horzScrollInfo = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
1446 if (!horzScrollInfo) break;
1447 horzScrollInfo->MinVal = horzScrollInfo->CurVal = horzScrollInfo->Page = 0;
1448 horzScrollInfo->MaxVal = 100;
1449 horzScrollInfo->flags = ESB_ENABLE_BOTH;
1450 }
1451 return horzScrollInfo;
1452
1453 case SB_VERT:
1454 if (!vertScrollInfo)
1455 {
1456 vertScrollInfo = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
1457 if (!vertScrollInfo) break;
1458 vertScrollInfo->MinVal = vertScrollInfo->CurVal = vertScrollInfo->Page = 0;
1459 vertScrollInfo->MaxVal = 100;
1460 vertScrollInfo->flags = ESB_ENABLE_BOTH;
1461 }
1462 return vertScrollInfo;
1463 }
1464
1465 return NULL;
1466}
1467//******************************************************************************
1468//******************************************************************************
1469LRESULT Win32BaseWindow::DefWndControlColor(UINT ctlType, HDC hdc)
1470{
1471 //SvL: Set background color to default button color (not window (white))
1472 if(ctlType == CTLCOLOR_BTN)
1473 {
1474 SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
1475 SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
1476 return GetSysColorBrush(COLOR_BTNFACE);
1477 }
1478 //SvL: Set background color to default dialog color if window is dialog
1479 if((ctlType == CTLCOLOR_DLG || ctlType == CTLCOLOR_STATIC) && IsDialog()) {
1480 SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
1481 SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
1482 return GetSysColorBrush(COLOR_BTNFACE);
1483 }
1484
1485 if( ctlType == CTLCOLOR_SCROLLBAR)
1486 {
1487 HBRUSH hb = GetSysColorBrush(COLOR_SCROLLBAR);
1488 COLORREF bk = GetSysColor(COLOR_3DHILIGHT);
1489 SetTextColor( hdc, GetSysColor(COLOR_3DFACE));
1490 SetBkColor( hdc, bk);
1491
1492//TODO?
1493#if 0
1494 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
1495 * we better use 0x55aa bitmap brush to make scrollbar's background
1496 * look different from the window background.
1497 */
1498 if (bk == GetSysColor(COLOR_WINDOW)) {
1499 return CACHE_GetPattern55AABrush();
1500 }
1501#endif
1502 UnrealizeObject( hb );
1503 return (LRESULT)hb;
1504 }
1505
1506 SetTextColor( hdc, GetSysColor(COLOR_WINDOWTEXT));
1507
1508 if ((ctlType == CTLCOLOR_EDIT) || (ctlType == CTLCOLOR_LISTBOX))
1509 {
1510 SetBkColor( hdc, GetSysColor(COLOR_WINDOW) );
1511 }
1512 else
1513 {
1514 SetBkColor( hdc, GetSysColor(COLOR_3DFACE) );
1515 return (LRESULT)GetSysColorBrush(COLOR_3DFACE);
1516 }
1517 return (LRESULT)GetSysColorBrush(COLOR_WINDOW);
1518}
1519//******************************************************************************
1520//******************************************************************************
1521LRESULT Win32BaseWindow::DefWndPrint(HDC hdc,ULONG uFlags)
1522{
1523 /*
1524 * Visibility flag.
1525 */
1526 if ( (uFlags & PRF_CHECKVISIBLE) &&
1527 !IsWindowVisible() )
1528 return 0;
1529
1530 /*
1531 * Unimplemented flags.
1532 */
1533 if ( (uFlags & PRF_CHILDREN) ||
1534 (uFlags & PRF_OWNED) ||
1535 (uFlags & PRF_NONCLIENT) )
1536 {
1537 dprintf(("WM_PRINT message with unsupported flags\n"));
1538 }
1539
1540 /*
1541 * Background
1542 */
1543 if ( uFlags & PRF_ERASEBKGND)
1544 SendInternalMessageA(WM_ERASEBKGND, (WPARAM)hdc, 0);
1545
1546 /*
1547 * Client area
1548 */
1549 if ( uFlags & PRF_CLIENT)
1550 SendInternalMessageA(WM_PRINTCLIENT, (WPARAM)hdc, PRF_CLIENT);
1551
1552
1553 return 0;
1554}
1555//******************************************************************************
1556//******************************************************************************
1557LRESULT Win32BaseWindow::DefWindowProcA(UINT Msg, WPARAM wParam, LPARAM lParam)
1558{
1559 switch(Msg)
1560 {
1561 case WM_CLOSE:
1562 dprintf(("DefWindowProcA: WM_CLOSE %x", getWindowHandle()));
1563 DestroyWindow();
1564 return 0;
1565
1566 case WM_GETTEXTLENGTH:
1567 return wndNameLength;
1568
1569 case WM_GETTEXT:
1570 if (!lParam || !wParam) return 0;
1571 if (!windowNameA) ((LPSTR)lParam)[0] = 0;
1572 else lstrcpynA((LPSTR)lParam, windowNameA, wParam);
1573 return min(wndNameLength, wParam);
1574
1575 case WM_SETTEXT:
1576 {
1577 LPCSTR lpsz = (LPCSTR)lParam;
1578
1579 if(windowNameA) free(windowNameA);
1580 if(windowNameW) free(windowNameW);
1581 if (lParam)
1582 {
1583 wndNameLength = strlen(lpsz);
1584 windowNameA = (LPSTR)_smalloc(wndNameLength+1);
1585 strcpy(windowNameA, lpsz);
1586 windowNameW = (LPWSTR)_smalloc((wndNameLength+1)*sizeof(WCHAR));
1587 lstrcpyAtoW(windowNameW, windowNameA);
1588 }
1589 else
1590 {
1591 windowNameA = NULL;
1592 windowNameW = NULL;
1593 wndNameLength = 0;
1594 }
1595 dprintf(("WM_SETTEXT of %x to %s\n", Win32Hwnd, lParam));
1596 if ((dwStyle & WS_CAPTION) == WS_CAPTION)
1597 {
1598 HandleNCPaint((HRGN)1);
1599 OSLibWinSetWindowText(OS2HwndFrame,(LPSTR)windowNameA);
1600 }
1601
1602 return TRUE;
1603 }
1604
1605 case WM_SETREDRAW:
1606 {
1607 if (wParam)
1608 {
1609 setStyle(getStyle() | WS_VISIBLE);
1610 OSLibWinEnableWindowUpdate(OS2HwndFrame,TRUE);
1611 }
1612 else
1613 {
1614 if (getStyle() & WS_VISIBLE)
1615 {
1616 setStyle(getStyle() & ~WS_VISIBLE);
1617 OSLibWinEnableWindowUpdate(OS2HwndFrame,FALSE);
1618 }
1619 }
1620 return 0;
1621 }
1622
1623 case WM_CTLCOLORMSGBOX:
1624 case WM_CTLCOLOREDIT:
1625 case WM_CTLCOLORLISTBOX:
1626 case WM_CTLCOLORBTN:
1627 case WM_CTLCOLORDLG:
1628 case WM_CTLCOLORSTATIC:
1629 case WM_CTLCOLORSCROLLBAR:
1630 return DefWndControlColor(Msg - WM_CTLCOLORMSGBOX, (HDC)wParam);
1631
1632 case WM_CTLCOLOR:
1633 return DefWndControlColor(HIWORD(lParam), (HDC)wParam);
1634
1635 case WM_VKEYTOITEM:
1636 case WM_CHARTOITEM:
1637 return -1;
1638
1639 case WM_PARENTNOTIFY:
1640 return 0;
1641
1642 case WM_MOUSEACTIVATE:
1643 {
1644 dprintf(("DefWndProc: WM_MOUSEACTIVATE for %x Msg %s", Win32Hwnd, GetMsgText(HIWORD(lParam))));
1645 if(getStyle() & WS_CHILD && !(getExStyle() & WS_EX_NOPARENTNOTIFY) )
1646 {
1647 if(getParent()) {
1648 LRESULT rc = getParent()->SendInternalMessageA(WM_MOUSEACTIVATE, wParam, lParam );
1649 if(rc) return rc;
1650 }
1651 }
1652 return (LOWORD(lParam) == HTCAPTION) ? MA_NOACTIVATE : MA_ACTIVATE;
1653 }
1654
1655 case WM_ACTIVATE:
1656 return 0;
1657
1658 case WM_SETCURSOR:
1659 {
1660 dprintf(("DefWndProc: WM_SETCURSOR for %x Msg %s", Win32Hwnd, GetMsgText(HIWORD(lParam))));
1661 if(getStyle() & WS_CHILD && !(getExStyle() & WS_EX_NOPARENTNOTIFY) )
1662 {
1663 if(getParent()) {
1664 LRESULT rc = getParent()->SendInternalMessageA(WM_SETCURSOR, wParam, lParam);
1665 if(rc) return rc;
1666 }
1667 }
1668 if (wParam == Win32Hwnd)
1669 {
1670 HCURSOR hCursor;
1671
1672 switch(LOWORD(lParam))
1673 {
1674 case HTCLIENT:
1675 hCursor = windowClass ? windowClass->getCursor():LoadCursorA(0,IDC_ARROWA);
1676 break;
1677
1678 case HTLEFT:
1679 case HTRIGHT:
1680 hCursor = LoadCursorA(0,IDC_SIZEWEA);
1681 break;
1682
1683 case HTTOP:
1684 case HTBOTTOM:
1685 hCursor = LoadCursorA(0,IDC_SIZENSA);
1686 break;
1687
1688 case HTTOPLEFT:
1689 case HTBOTTOMRIGHT:
1690 hCursor = LoadCursorA(0,IDC_SIZENWSEA);
1691 break;
1692
1693 case HTTOPRIGHT:
1694 case HTBOTTOMLEFT:
1695 hCursor = LoadCursorA(0,IDC_SIZENESWA);
1696 break;
1697
1698 default:
1699 hCursor = LoadCursorA(0,IDC_ARROWA);
1700 break;
1701 }
1702
1703 if (hCursor)
1704 {
1705 SetCursor(hCursor);
1706 return 1;
1707 }
1708 else return 0;
1709 }
1710 else return 0;
1711 }
1712
1713 case WM_MOUSEMOVE:
1714 return 0;
1715
1716 case WM_WINDOWPOSCHANGED:
1717 {
1718 PWINDOWPOS wpos = (PWINDOWPOS)lParam;
1719 WPARAM wp = SIZE_RESTORED;
1720
1721 if (!(wpos->flags & SWP_NOMOVE) && !(wpos->flags & SWP_NOCLIENTMOVE))
1722 {
1723 SendInternalMessageA(WM_MOVE, 0, MAKELONG(rectClient.left,rectClient.top));
1724 }
1725 if (!(wpos->flags & SWP_NOSIZE) && !(wpos->flags & SWP_NOCLIENTSIZE))
1726 {
1727 if (dwStyle & WS_MAXIMIZE) wp = SIZE_MAXIMIZED;
1728 else
1729 if (dwStyle & WS_MINIMIZE) wp = SIZE_MINIMIZED;
1730
1731 SendInternalMessageA(WM_SIZE, wp, MAKELONG(rectClient.right - rectClient.left,
1732 rectClient.bottom - rectClient.top));
1733 }
1734 return 0;
1735 }
1736 case WM_WINDOWPOSCHANGING:
1737 return HandleWindowPosChanging((WINDOWPOS *)lParam);
1738
1739 case WM_ERASEBKGND:
1740 case WM_ICONERASEBKGND:
1741 {
1742 RECT rect;
1743 int rc;
1744
1745 if (!windowClass || !windowClass->getBackgroundBrush()) return 0;
1746
1747 rc = GetClipBox( (HDC)wParam, &rect );
1748 if ((rc == SIMPLEREGION) || (rc == COMPLEXREGION))
1749 {
1750 HBRUSH hBrush = windowClass->getBackgroundBrush();
1751
1752 if (hBrush <= (HBRUSH)(SYSCOLOR_GetLastColor()+1))
1753 hBrush = GetSysColorBrush(hBrush-1);
1754
1755 FillRect( (HDC)wParam, &rect, hBrush);
1756 }
1757 return 1;
1758 }
1759
1760 case WM_PRINT:
1761 return DefWndPrint(wParam,lParam);
1762
1763 case WM_PAINTICON:
1764 case WM_PAINT:
1765 {
1766 PAINTSTRUCT ps;
1767 HDC hdc = BeginPaint(getWindowHandle(), &ps );
1768 if( hdc )
1769 {
1770 if( (getStyle() & WS_MINIMIZE) && getWindowClass()->getIcon())
1771 {
1772 int x = (rectWindow.right - rectWindow.left - GetSystemMetrics(SM_CXICON))/2;
1773 int y = (rectWindow.bottom - rectWindow.top - GetSystemMetrics(SM_CYICON))/2;
1774 dprintf(("Painting class icon: vis rect=(%i,%i - %i,%i)\n", ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom ));
1775 DrawIcon(hdc, x, y, getWindowClass()->getIcon() );
1776 }
1777 EndPaint(getWindowHandle(), &ps );
1778 }
1779 return 0;
1780 }
1781
1782 case WM_GETDLGCODE:
1783 return 0;
1784
1785 case WM_NCPAINT:
1786 return HandleNCPaint((HRGN)wParam);
1787
1788 case WM_NCACTIVATE:
1789 return HandleNCActivate(wParam);
1790
1791 case WM_NCCREATE:
1792 return(TRUE);
1793
1794 case WM_NCDESTROY:
1795 return 0;
1796
1797 case WM_NCCALCSIZE:
1798 return HandleNCCalcSize((BOOL)wParam,(RECT*)lParam);
1799
1800 case WM_NCLBUTTONDOWN:
1801 return HandleNCLButtonDown(wParam,lParam);
1802
1803 case WM_LBUTTONDBLCLK:
1804 case WM_NCLBUTTONDBLCLK:
1805 return HandleNCLButtonDblClk(wParam,lParam);
1806
1807 case WM_NCRBUTTONDOWN:
1808 case WM_NCRBUTTONDBLCLK:
1809 case WM_NCMBUTTONDOWN:
1810 case WM_NCMBUTTONDBLCLK:
1811 if (lastHitTestVal == HTERROR) MessageBeep(MB_ICONEXCLAMATION);
1812 return 0;
1813
1814 case WM_NCRBUTTONUP:
1815 return HandleNCRButtonUp(wParam,lParam);
1816
1817 case WM_NCMBUTTONUP:
1818 return 0;
1819
1820 case WM_NCHITTEST:
1821 {
1822 POINT point;
1823
1824 point.x = (SHORT)LOWORD(lParam);
1825 point.y = (SHORT)HIWORD(lParam);
1826
1827 return HandleNCHitTest(point);
1828 }
1829
1830 case WM_SYSCOMMAND:
1831 {
1832 POINT point;
1833
1834 point.x = LOWORD(lParam);
1835 point.y = HIWORD(lParam);
1836 return HandleSysCommand(wParam,&point);
1837 }
1838
1839 case WM_SYSKEYDOWN:
1840 if(wParam == VK_F4) /* try to close the window */
1841 {
1842 Win32BaseWindow *window = GetTopParent();
1843 if(window && !(window->getClass()->getStyle() & CS_NOCLOSE))
1844 PostMessageA(getWindowHandle(), WM_SYSCOMMAND, SC_CLOSE, 0);
1845 }
1846
1847 Win32BaseWindow *siblingWindow;
1848 HWND sibling;
1849 char nameBuffer [40], mnemonic;
1850 int nameLength;
1851
1852 GetWindowTextA (nameBuffer, 40);
1853
1854 // search all sibling to see it this key is their mnemonic
1855 sibling = GetWindow (GW_HWNDFIRST);
1856 while (sibling != 0) {
1857 siblingWindow = GetWindowFromHandle (sibling);
1858 nameLength = siblingWindow->GetWindowTextA (nameBuffer, 40);
1859
1860 // find the siblings mnemonic
1861 mnemonic = '\0';
1862 for (int i=0 ; i<nameLength ; i++) {
1863 if (nameBuffer [i] == '&') {
1864 mnemonic = nameBuffer [i+1];
1865 if ((mnemonic >= 'a') && (mnemonic <= 'z'))
1866 mnemonic -= 32; // make it uppercase
1867 break; // stop searching
1868 }
1869 }
1870
1871 // key matches siblings mnemonic, send mouseclick
1872 if (mnemonic == (char) wParam) {
1873 siblingWindow->SendInternalMessageA (BM_CLICK, 0, 0);
1874 }
1875
1876 sibling = siblingWindow->GetNextWindow (GW_HWNDNEXT);
1877 }
1878
1879 return 0;
1880
1881 case WM_SYSCHAR:
1882 {
1883 int iMenuSysKey = 0;
1884 if (wParam == VK_RETURN && (getStyle() & WS_MINIMIZE))
1885 {
1886 PostMessageA(getWindowHandle(), WM_SYSCOMMAND,
1887 (WPARAM)SC_RESTORE, 0L );
1888 break;
1889 }
1890 if ((HIWORD(lParam) & KEYDATA_ALT) && wParam)
1891 {
1892 if (wParam == VK_TAB || wParam == VK_ESCAPE) break;
1893 if (wParam == VK_SPACE && (getStyle() & WS_CHILD))
1894 getParent()->SendMessageA(Msg, wParam, lParam );
1895 else
1896 SendMessageA(WM_SYSCOMMAND, (WPARAM)SC_KEYMENU, (LPARAM)(DWORD)wParam );
1897 }
1898 else /* check for Ctrl-Esc */
1899 if (wParam != VK_ESCAPE) MessageBeep(0);
1900 break;
1901 }
1902 case WM_SETHOTKEY:
1903 hotkey = wParam;
1904 return 1; //CB: always successful
1905
1906 case WM_GETHOTKEY:
1907 return hotkey;
1908
1909 case WM_CONTEXTMENU:
1910 if ((dwStyle & WS_CHILD) && getParent())
1911 getParent()->SendInternalMessageA(WM_CONTEXTMENU,wParam,lParam);
1912 return 0;
1913
1914 case WM_SHOWWINDOW:
1915 if (!lParam) return 0; /* sent from ShowWindow */
1916 if (!(dwStyle & WS_POPUP) || !owner) return 0;
1917 if ((dwStyle & WS_VISIBLE) && wParam) return 0;
1918 else if (!(dwStyle & WS_VISIBLE) && !wParam) return 0;
1919 ShowWindow(wParam ? SW_SHOWNOACTIVATE : SW_HIDE);
1920 return 0;
1921
1922 case WM_CANCELMODE:
1923 if (getParent() == windowDesktop) EndMenu();
1924 if (GetCapture() == Win32Hwnd) ReleaseCapture();
1925 return 0;
1926
1927 case WM_DROPOBJECT:
1928 return DRAG_FILE;
1929
1930 case WM_QUERYDROPOBJECT:
1931 return (dwExStyle & WS_EX_ACCEPTFILES) ? 1:0;
1932
1933 case WM_QUERYDRAGICON:
1934 {
1935 HICON hIcon = windowClass->getCursor();
1936 UINT len;
1937
1938 if(hIcon) return (LRESULT)hIcon;
1939 for(len = 1; len < 64; len++)
1940 {
1941 hIcon = LoadIconA(hInstance,MAKEINTRESOURCEA(len));
1942 if(hIcon)
1943 return (LRESULT)hIcon;
1944 }
1945 return (LRESULT)LoadIconA(0,IDI_APPLICATIONA);
1946 }
1947
1948 case WM_QUERYOPEN:
1949 case WM_QUERYENDSESSION:
1950 return 1;
1951
1952 case WM_NOTIFYFORMAT:
1953 return IsWindowUnicode() ? NFR_UNICODE:NFR_ANSI;
1954
1955 case WM_SETICON:
1956 case WM_GETICON:
1957 {
1958 LRESULT result = 0;
1959 if (!windowClass) return result;
1960 int index = GCL_HICON;
1961
1962 if (wParam == ICON_SMALL)
1963 index = GCL_HICONSM;
1964
1965 result = windowClass->getClassLongA(index);
1966
1967 if (Msg == WM_SETICON)
1968 windowClass->setClassLongA(index, lParam);
1969
1970 return result;
1971 }
1972
1973 case WM_NOTIFY:
1974 return 0; //comctl32 controls expect this
1975
1976 default:
1977 return 0;
1978 }
1979 return 0;
1980}
1981//******************************************************************************
1982//******************************************************************************
1983LRESULT Win32BaseWindow::DefWindowProcW(UINT Msg, WPARAM wParam, LPARAM lParam)
1984{
1985 switch(Msg)
1986 {
1987 case WM_GETTEXTLENGTH:
1988 return wndNameLength;
1989
1990 case WM_GETTEXT:
1991 if (!lParam || !wParam) return 0;
1992 if (!windowNameW) ((LPWSTR)lParam)[0] = 0;
1993 else lstrcpynW((LPWSTR)lParam,windowNameW,wParam);
1994 return min(wndNameLength,wParam);
1995
1996 case WM_SETTEXT:
1997 {
1998 LPWSTR lpsz = (LPWSTR)lParam;
1999
2000 if(windowNameA) free(windowNameA);
2001 if(windowNameW) free(windowNameW);
2002 if (lParam)
2003 {
2004 wndNameLength = lstrlenW(lpsz);
2005 windowNameA = (LPSTR)_smalloc(wndNameLength+1);
2006 lstrcpyWtoA(windowNameA,lpsz);
2007 windowNameW = (LPWSTR)_smalloc((wndNameLength+1)*sizeof(WCHAR));
2008 lstrcpyW(windowNameW,lpsz);
2009 }
2010 else
2011 {
2012 windowNameA = NULL;
2013 windowNameW = NULL;
2014 wndNameLength = 0;
2015 }
2016 dprintf(("WM_SETTEXT of %x\n",Win32Hwnd));
2017 if ((dwStyle & WS_CAPTION) == WS_CAPTION)
2018 {
2019 HandleNCPaint((HRGN)1);
2020 OSLibWinSetWindowText(OS2HwndFrame,(LPSTR)windowNameA);
2021 }
2022
2023 return TRUE;
2024 }
2025
2026 default:
2027 return DefWindowProcA(Msg, wParam, lParam);
2028 }
2029}
2030//******************************************************************************
2031//******************************************************************************
2032LRESULT Win32BaseWindow::SendMessageA(ULONG Msg, WPARAM wParam, LPARAM lParam)
2033{
2034 //if the destination window is created by this process & thread, call window proc directly
2035 if(dwProcessId == currentProcessId && dwThreadId == GetCurrentThreadId()) {
2036 return SendInternalMessageA(Msg, wParam, lParam);
2037 }
2038 //otherwise use WinSendMsg to send it to the right process/thread
2039 return OSLibSendMessage(getOS2WindowHandle(), Msg, wParam, lParam, FALSE);
2040}
2041//******************************************************************************
2042//******************************************************************************
2043LRESULT Win32BaseWindow::SendMessageW(ULONG Msg, WPARAM wParam, LPARAM lParam)
2044{
2045 //if the destination window is created by this process & thread, call window proc directly
2046 if(dwProcessId == currentProcessId && dwThreadId == GetCurrentThreadId()) {
2047 return SendInternalMessageW(Msg, wParam, lParam);
2048 }
2049 //otherwise use WinSendMsg to send it to the right process/thread
2050 return OSLibSendMessage(getOS2WindowHandle(), Msg, wParam, lParam, TRUE);
2051}
2052//******************************************************************************
2053//Called as a result of an OS/2 message or called from a class method
2054//******************************************************************************
2055LRESULT Win32BaseWindow::SendInternalMessageA(ULONG Msg, WPARAM wParam, LPARAM lParam)
2056{
2057 LRESULT rc;
2058 BOOL fInternalMsgBackup = fInternalMsg;
2059
2060 DebugPrintMessage(getWindowHandle(), Msg, wParam, lParam, FALSE, TRUE);
2061
2062 CallWindowHookProc(WH_CALLWNDPROC, Msg, wParam, lParam, FALSE);
2063
2064 fInternalMsg = TRUE;
2065 switch(Msg)
2066 {
2067 case WM_CREATE:
2068 {
2069 if(CallWindowProcA(win32wndproc, getWindowHandle(), WM_CREATE, 0, lParam) == -1) {
2070 dprintf(("WM_CREATE returned -1\n"));
2071 rc = -1; //don't create window
2072 break;
2073 }
2074 rc = 0;
2075 break;
2076 }
2077 case WM_LBUTTONDOWN:
2078 case WM_MBUTTONDOWN:
2079 case WM_RBUTTONDOWN:
2080 {
2081 if (getParent())
2082 {
2083 POINTS pt = MAKEPOINTS(lParam);
2084 POINT point;
2085
2086 point.x = pt.x;
2087 point.y = pt.y;
2088 mapWin32Point(OS2Hwnd,getParent()->getOS2WindowHandle(),(OSLIBPOINT*)&point);
2089 NotifyParent(Msg,wParam,MAKELPARAM(point.x,point.y));
2090 }
2091 rc = win32wndproc(getWindowHandle(), Msg, wParam, lParam);
2092 break;
2093 }
2094
2095 case WM_DESTROY:
2096 rc = win32wndproc(getWindowHandle(), WM_DESTROY, 0, 0);
2097 break;
2098
2099 default:
2100 rc = CallWindowProcA(win32wndproc, getWindowHandle(), Msg, wParam, lParam);
2101 break;
2102 }
2103 fInternalMsg = fInternalMsgBackup;
2104 return rc;
2105}
2106//******************************************************************************
2107//Called as a result of an OS/2 message or called from a class method
2108//******************************************************************************
2109LRESULT Win32BaseWindow::SendInternalMessageW(ULONG Msg, WPARAM wParam, LPARAM lParam)
2110{
2111 LRESULT rc;
2112 BOOL fInternalMsgBackup = fInternalMsg;
2113
2114 DebugPrintMessage(getWindowHandle(), Msg, wParam, lParam, TRUE, TRUE);
2115
2116 CallWindowHookProc(WH_CALLWNDPROC, Msg, wParam, lParam, TRUE);
2117
2118 fInternalMsg = TRUE;
2119 switch(Msg)
2120 {
2121 case WM_CREATE:
2122 {
2123 if(CallWindowProcW(win32wndproc, getWindowHandle(), WM_CREATE, 0, lParam) == -1) {
2124 dprintf(("WM_CREATE returned -1\n"));
2125 rc = -1; //don't create window
2126 break;
2127 }
2128 rc = 0;
2129 break;
2130 }
2131 case WM_LBUTTONDOWN:
2132 case WM_MBUTTONDOWN:
2133 case WM_RBUTTONDOWN:
2134 NotifyParent(Msg, wParam, lParam);
2135 rc = win32wndproc(getWindowHandle(), Msg, wParam, lParam);
2136 break;
2137
2138 case WM_DESTROY:
2139 rc = win32wndproc(getWindowHandle(), WM_DESTROY, 0, 0);
2140 break;
2141 default:
2142 rc = CallWindowProcW(win32wndproc, getWindowHandle(), Msg, wParam, lParam);
2143 break;
2144 }
2145 fInternalMsg = fInternalMsgBackup;
2146 return rc;
2147}
2148//******************************************************************************
2149//******************************************************************************
2150void Win32BaseWindow::CallWindowHookProc(ULONG hooktype, ULONG Msg, WPARAM wParam, LPARAM lParam, BOOL fUnicode)
2151{
2152 CWPSTRUCT cwp;
2153
2154 cwp.lParam = lParam;
2155 cwp.wParam = wParam;
2156 cwp.message = Msg;
2157 cwp.hwnd = getWindowHandle();
2158
2159 switch(hooktype) {
2160 case WH_CALLWNDPROC:
2161 if(fUnicode) {
2162 HOOK_CallHooksW(WH_CALLWNDPROC, HC_ACTION, 1, (LPARAM)&cwp);
2163 }
2164 else HOOK_CallHooksA(WH_CALLWNDPROC, HC_ACTION, 1, (LPARAM)&cwp);
2165 break;
2166 }
2167}
2168//******************************************************************************
2169//TODO: Do this more efficiently
2170//******************************************************************************
2171LRESULT Win32BaseWindow::BroadcastMessageA(int type, UINT msg, WPARAM wParam, LPARAM lParam)
2172{
2173 Win32BaseWindow *window;
2174 HWND hwnd = WNDHANDLE_MAGIC_HIGHWORD;
2175
2176 dprintf(("BroadCastMessageA %x %x %x", msg, wParam, lParam, GetFS()));
2177
2178 for(int i=0;i<MAX_WINDOW_HANDLES;i++) {
2179 window = GetWindowFromHandle(hwnd++);
2180 if(window) {
2181 if ((window->getStyle() & WS_POPUP) || ((window->getStyle() & WS_CAPTION) == WS_CAPTION))
2182 {
2183
2184 if(type == BROADCAST_SEND) {
2185 window->SendInternalMessageA(msg, wParam, lParam);
2186 }
2187 else PostMessageA(window->getWindowHandle(), msg, wParam, lParam);
2188 }
2189 }
2190 }
2191 return 0;
2192}
2193//******************************************************************************
2194//TODO: Do this more efficiently
2195//******************************************************************************
2196LRESULT Win32BaseWindow::BroadcastMessageW(int type, UINT msg, WPARAM wParam, LPARAM lParam)
2197{
2198 Win32BaseWindow *window;
2199 HWND hwnd = WNDHANDLE_MAGIC_HIGHWORD;
2200
2201 dprintf(("BroadCastMessageW %x %x %x", msg, wParam, lParam));
2202
2203 for(int i=0;i<MAX_WINDOW_HANDLES;i++) {
2204 window = GetWindowFromHandle(hwnd++);
2205 if(window) {
2206 if ((window->getStyle() & WS_POPUP) || ((window->getStyle() & WS_CAPTION) == WS_CAPTION))
2207 {
2208
2209 if(type == BROADCAST_SEND) {
2210 window->SendInternalMessageW(msg, wParam, lParam);
2211 }
2212 else PostMessageW(window->getWindowHandle(), msg, wParam, lParam);
2213 }
2214 }
2215 }
2216 return 0;
2217}
2218//******************************************************************************
2219//******************************************************************************
2220void Win32BaseWindow::NotifyParent(UINT Msg, WPARAM wParam, LPARAM lParam)
2221{
2222 Win32BaseWindow *window = this;
2223 Win32BaseWindow *parentwindow;
2224
2225 while(window)
2226 {
2227 if(window->getStyle() & WS_CHILD && !(window->getExStyle() & WS_EX_NOPARENTNOTIFY) )
2228 {
2229 /* Notify the parent window only */
2230 parentwindow = window->getParent();
2231 if(parentwindow) {
2232 parentwindow->SendInternalMessageA(WM_PARENTNOTIFY, MAKEWPARAM(Msg, getWindowId()), lParam );
2233 }
2234 }
2235 else break;
2236
2237 window = parentwindow;
2238 }
2239}
2240//******************************************************************************
2241//******************************************************************************
2242BOOL Win32BaseWindow::SetIcon(HICON hIcon)
2243{
2244 dprintf(("Win32BaseWindow::SetIcon %x", hIcon));
2245 if(OSLibWinSetIcon(OS2HwndFrame, hIcon) == TRUE) {
2246//TODO: Wine does't send these. Correct?
2247// SendInternalMessageA(WM_SETICON, ICON_BIG, hIcon);
2248 return TRUE;
2249 }
2250 return FALSE;
2251}
2252//******************************************************************************
2253//******************************************************************************
2254BOOL Win32BaseWindow::ShowWindow(ULONG nCmdShow)
2255{
2256 ULONG showstate = 0;
2257 HWND hWinAfter;
2258
2259 dprintf(("ShowWindow %x %x", getWindowHandle(), nCmdShow));
2260
2261 if (flags & WIN_NEED_SIZE)
2262 {
2263 /* should happen only in CreateWindowEx() */
2264 int wParam = SIZE_RESTORED;
2265
2266 flags &= ~WIN_NEED_SIZE;
2267 if (dwStyle & WS_MAXIMIZE)
2268 wParam = SIZE_MAXIMIZED;
2269 else
2270 if (dwStyle & WS_MINIMIZE)
2271 wParam = SIZE_MINIMIZED;
2272
2273 SendInternalMessageA(WM_SIZE, wParam,
2274 MAKELONG(rectClient.right-rectClient.left,
2275 rectClient.bottom-rectClient.top));
2276 SendInternalMessageA(WM_MOVE,0,MAKELONG(rectClient.left,rectClient.top));
2277 }
2278 switch(nCmdShow)
2279 {
2280 case SW_SHOW:
2281 case SW_SHOWDEFAULT: //todo
2282 showstate = SWPOS_SHOW | SWPOS_ACTIVATE;
2283 break;
2284 case SW_HIDE:
2285 showstate = SWPOS_HIDE;
2286 break;
2287 case SW_RESTORE:
2288 showstate = SWPOS_RESTORE | SWPOS_SHOW | SWPOS_ACTIVATE;
2289 break;
2290 case SW_MINIMIZE:
2291 showstate = SWPOS_MINIMIZE;
2292 break;
2293 case SW_SHOWMAXIMIZED:
2294 showstate = SWPOS_MAXIMIZE | SWPOS_SHOW | SWPOS_ACTIVATE;
2295 break;
2296 case SW_SHOWMINIMIZED:
2297 showstate = SWPOS_MINIMIZE | SWPOS_SHOW | SWPOS_ACTIVATE;
2298 break;
2299 case SW_SHOWMINNOACTIVE:
2300 showstate = SWPOS_MINIMIZE | SWPOS_SHOW;
2301 break;
2302 case SW_SHOWNA:
2303 showstate = SWPOS_SHOW;
2304 break;
2305 case SW_SHOWNOACTIVATE:
2306 showstate = SWPOS_SHOW;
2307 break;
2308 case SW_SHOWNORMAL:
2309 showstate = SWPOS_RESTORE | SWPOS_ACTIVATE | SWPOS_SHOW;
2310 break;
2311 }
2312
2313 /* We can't activate a child window (WINE) */
2314 if(getStyle() & WS_CHILD)
2315 showstate &= ~SWPOS_ACTIVATE;
2316
2317 if(showstate & SWPOS_SHOW) {
2318 setStyle(getStyle() | WS_VISIBLE);
2319 }
2320 else setStyle(getStyle() & ~WS_VISIBLE);
2321
2322 BOOL rc = OSLibWinShowWindow(OS2HwndFrame, showstate);
2323
2324 return rc;
2325}
2326//******************************************************************************
2327//******************************************************************************
2328BOOL Win32BaseWindow::SetWindowPos(HWND hwndInsertAfter, int x, int y, int cx, int cy, UINT fuFlags)
2329{
2330 BOOL rc = FALSE;
2331 Win32BaseWindow *window;
2332 HWND hParent = 0;
2333 BOOL fShow = FALSE, fHide = FALSE;
2334
2335 if (fuFlags &
2336 ~(SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER |
2337 SWP_NOREDRAW | SWP_NOACTIVATE | SWP_FRAMECHANGED |
2338 SWP_SHOWWINDOW | SWP_HIDEWINDOW | SWP_NOCOPYBITS |
2339 SWP_NOOWNERZORDER))
2340 {
2341 return FALSE;
2342 }
2343
2344 if(IsWindowDestroyed()) {
2345 //changing the position of a window that's being destroyed can cause crashes in PMMERGE
2346 dprintf(("SetWindowPos; window already destroyed"));
2347 return TRUE;
2348 }
2349 WINDOWPOS wpos;
2350 SWP swp, swpOld;
2351
2352#if 0 //CB: test: MSIE 2.0 displays the tool-/addressbar this way -> to check
2353 //CB: -> comctl32: toolbar (WM_SIZE), same bug: statusbar height
2354 //CB: cx or cy are 0
2355
2356if (cx == 0)
2357{
2358 dprintf(("CB: cx is 0! %d",fuFlags));
2359 if (fuFlags & SWP_NOSIZE) dprintf(("CB: nosize"));
2360 cx = 50;
2361}
2362if (cy == 0)
2363{
2364 dprintf(("CB: cy is 0! %d",fuFlags));
2365 if (fuFlags & SWP_NOSIZE) dprintf(("CB: nosize"));
2366 cy = 50;
2367}
2368
2369#endif
2370
2371 if(fuFlags & SWP_SHOWWINDOW) {
2372 fShow = TRUE;
2373 fuFlags &= ~SWP_SHOWWINDOW;
2374 }
2375 else
2376 if(fuFlags & SWP_HIDEWINDOW) {
2377 fHide = TRUE;
2378 fuFlags &= ~SWP_HIDEWINDOW;
2379 }
2380 wpos.flags = fuFlags;
2381 wpos.cy = cy;
2382 wpos.cx = cx;
2383 wpos.x = x;
2384 wpos.y = y;
2385 wpos.hwndInsertAfter = hwndInsertAfter;
2386 wpos.hwnd = getWindowHandle();
2387
2388 if(~fuFlags & (SWP_NOMOVE | SWP_NOSIZE))
2389 {
2390 if (isChild())
2391 {
2392 Win32BaseWindow *windowParent = getParent();
2393 if(windowParent) {
2394 hParent = getParent()->getOS2WindowHandle();
2395 }
2396 else dprintf(("WARNING: Win32BaseWindow::SetWindowPos window %x is child but has no parent!!", getWindowHandle()));
2397 }
2398 OSLibWinQueryWindowPos(OS2HwndFrame, &swpOld);
2399 }
2400
2401 OSLibMapWINDOWPOStoSWP(&wpos, &swp, &swpOld, hParent, OS2HwndFrame);
2402 if (swp.fl == 0) {
2403 if (fuFlags & SWP_FRAMECHANGED)
2404 {
2405 FrameUpdateClient(this);
2406 }
2407 return TRUE;
2408 }
2409
2410// if ((swp.fl & SWPOS_ZORDER) && (swp.hwndInsertBehind > HWNDOS_BOTTOM))
2411 if ((swp.hwndInsertBehind > HWNDOS_BOTTOM))
2412 {
2413 Win32BaseWindow *wndBehind = Win32BaseWindow::GetWindowFromHandle(swp.hwndInsertBehind);
2414 if(wndBehind) {
2415 swp.hwndInsertBehind = wndBehind->getOS2FrameWindowHandle();
2416 }
2417 else {
2418 dprintf(("ERROR: SetWindowPos: hwndInsertBehind %x invalid!",swp.hwndInsertBehind));
2419 swp.hwndInsertBehind = 0;
2420 }
2421 }
2422 swp.hwnd = OS2HwndFrame;
2423
2424 dprintf (("WinSetWindowPos %x %x (%d,%d)(%d,%d) %x", swp.hwnd, swp.hwndInsertBehind, swp.x, swp.y, swp.cx, swp.cy, swp.fl));
2425
2426 //SvL: For some reason WinSetMultWindowPos doesn't work for showing windows when they are hidden..
2427 if(fHide) {
2428 ShowWindow(SW_HIDE);
2429 }
2430 rc = OSLibWinSetMultWindowPos(&swp, 1);
2431 if(fShow) {
2432 ShowWindow(SW_SHOWNA);
2433 }
2434
2435 if (rc == FALSE)
2436 {
2437 dprintf(("OSLibWinSetMultWindowPos failed! Error %x",OSLibWinGetLastError()));
2438 }
2439
2440 if(fuFlags & SWP_FRAMECHANGED && (fuFlags & (SWP_NOMOVE | SWP_NOSIZE) == (SWP_NOMOVE | SWP_NOSIZE)))
2441 {
2442 FrameUpdateClient(this);
2443 }
2444
2445 return (rc);
2446}
2447//******************************************************************************
2448//TODO: WPF_RESTOREMAXIMIZED
2449//******************************************************************************
2450BOOL Win32BaseWindow::SetWindowPlacement(WINDOWPLACEMENT *winpos)
2451{
2452 if(isFrameWindow())
2453 {
2454 // Set the minimized position
2455 if (winpos->flags & WPF_SETMINPOSITION)
2456 {
2457 OSLibSetWindowMinPos(OS2HwndFrame, winpos->ptMinPosition.x, winpos->ptMinPosition.y);
2458 }
2459
2460 //TODO: Max position
2461
2462 // Set the new restore position.
2463 OSLibSetWindowRestoreRect(OS2HwndFrame, &winpos->rcNormalPosition);
2464 }
2465
2466 return ShowWindow(winpos->showCmd);
2467}
2468//******************************************************************************
2469//Also destroys all the child windows (destroy children first, parent last)
2470//******************************************************************************
2471BOOL Win32BaseWindow::DestroyWindow()
2472{
2473 /* Call hooks */
2474 if(HOOK_CallHooksA( WH_CBT, HCBT_DESTROYWND, getWindowHandle(), 0L))
2475 {
2476 return FALSE;
2477 }
2478
2479 if(!(getStyle() & WS_CHILD) && getOwner() == NULL)
2480 {
2481 HOOK_CallHooksA(WH_SHELL, HSHELL_WINDOWDESTROYED, getWindowHandle(), 0L);
2482 /* FIXME: clean up palette - see "Internals" p.352 */
2483 }
2484
2485 if((getStyle() & WS_CHILD) && !(getExStyle() & WS_EX_NOPARENTNOTIFY))
2486 {
2487 if(getParent())
2488 {
2489 /* Notify the parent window only */
2490 getParent()->SendMessageA(WM_PARENTNOTIFY, MAKEWPARAM(WM_DESTROY, getWindowId()), (LPARAM)getWindowHandle());
2491 if( !::IsWindow(getWindowHandle()) )
2492 {
2493 return TRUE;
2494 }
2495 }
2496 else DebugInt3();
2497 }
2498 fDestroyWindowCalled = TRUE;
2499 return OSLibWinDestroyWindow(OS2HwndFrame);
2500}
2501//******************************************************************************
2502//******************************************************************************
2503Win32BaseWindow *Win32BaseWindow::getParent()
2504{
2505 Win32BaseWindow *wndparent = (Win32BaseWindow *)ChildWindow::GetParent();
2506 return ((ULONG)wndparent == (ULONG)windowDesktop) ? NULL : wndparent;
2507}
2508//******************************************************************************
2509//******************************************************************************
2510HWND Win32BaseWindow::GetParent()
2511{
2512 Win32BaseWindow *wndparent;
2513
2514 if ((!(getStyle() & (WS_POPUP|WS_CHILD))))
2515 {
2516 return 0;
2517 }
2518 wndparent = ((getStyle() & WS_CHILD) ? getParent() : getOwner());
2519
2520 return (wndparent) ? wndparent->getWindowHandle() : 0;
2521}
2522//******************************************************************************
2523//******************************************************************************
2524HWND Win32BaseWindow::SetParent(HWND hwndNewParent)
2525{
2526 HWND oldhwnd;
2527 Win32BaseWindow *newparent;
2528
2529 if(getParent()) {
2530 oldhwnd = getParent()->getWindowHandle();
2531 getParent()->RemoveChild(this);
2532 }
2533 else oldhwnd = 0;
2534
2535 newparent = GetWindowFromHandle(hwndNewParent);
2536 if(newparent)
2537 {
2538 setParent(newparent);
2539 getParent()->AddChild(this);
2540 OSLibWinSetParent(getOS2FrameWindowHandle(), getParent()->getOS2WindowHandle());
2541 return oldhwnd;
2542 }
2543 else {
2544 setParent(windowDesktop);
2545 windowDesktop->AddChild(this);
2546 OSLibWinSetParent(getOS2FrameWindowHandle(), OSLIB_HWND_DESKTOP);
2547 return oldhwnd;
2548 }
2549}
2550//******************************************************************************
2551//******************************************************************************
2552BOOL Win32BaseWindow::IsChild(HWND hwndParent)
2553{
2554 if(getParent()) {
2555 return getParent()->getWindowHandle() == hwndParent;
2556 }
2557 else return 0;
2558}
2559//******************************************************************************
2560//******************************************************************************
2561HWND Win32BaseWindow::GetTopWindow()
2562{
2563 return GetWindow(GW_CHILD);
2564}
2565//******************************************************************************
2566// Get the top-level parent for a child window.
2567//******************************************************************************
2568Win32BaseWindow *Win32BaseWindow::GetTopParent()
2569{
2570 Win32BaseWindow *window = this;
2571
2572 while(window && (window->getStyle() & WS_CHILD))
2573 {
2574 window = window->getParent();
2575 }
2576 return window;
2577}
2578//******************************************************************************
2579//Don't call WinUpdateWindow as that one also updates the child windows
2580//Also need to send WM_PAINT directly to the window procedure, which doesn't
2581//always happen with WinUpdateWindow (could be posted if thread doesn't own window)
2582//******************************************************************************
2583BOOL Win32BaseWindow::UpdateWindow()
2584{
2585 RECT rect;
2586
2587 if(OSLibWinQueryUpdateRect(OS2Hwnd, &rect))
2588 {//update region not empty
2589 HDC hdc;
2590
2591 hdc = O32_GetDC(OS2Hwnd);
2592 if (isIcon)
2593 {
2594 SendInternalMessageA(WM_ICONERASEBKGND, (WPARAM)hdc, 0);
2595 SendInternalMessageA(WM_PAINTICON, 0, 0);
2596 }
2597 else
2598 {
2599 SendInternalMessageA(WM_ERASEBKGND, (WPARAM)hdc, 0);
2600 SendInternalMessageA(WM_PAINT, 0, 0);
2601 }
2602 O32_ReleaseDC(OS2Hwnd, hdc);
2603 }
2604 return TRUE;
2605}
2606//******************************************************************************
2607//******************************************************************************
2608BOOL Win32BaseWindow::IsIconic()
2609{
2610 return OSLibWinIsIconic(OS2Hwnd);
2611}
2612//******************************************************************************
2613//TODO: Should not enumerate children that are created during the enumeration!
2614//******************************************************************************
2615BOOL Win32BaseWindow::EnumChildWindows(WNDENUMPROC lpfn, LPARAM lParam)
2616{
2617 BOOL rc = TRUE;
2618 HWND hwnd;
2619 Win32BaseWindow *prevchild = 0, *child = 0;
2620
2621 dprintf(("EnumChildWindows of %x parameter %x %x (%x)", getWindowHandle(), lpfn, lParam, getFirstChild()));
2622 for (child = (Win32BaseWindow *)getFirstChild(); child; child = (Win32BaseWindow *)child->getNextChild())
2623 {
2624 dprintf(("EnumChildWindows: enumerating child %x", child->getWindowHandle()));
2625 hwnd = child->getWindowHandle();
2626 if(child->getOwner()) {
2627 continue; //shouldn't have an owner (Wine)
2628 }
2629 if(lpfn(hwnd, lParam) == FALSE)
2630 {
2631 rc = FALSE;
2632 break;
2633 }
2634 //check if the window still exists
2635 if(!::IsWindow(hwnd))
2636 {
2637 child = prevchild;
2638 continue;
2639 }
2640 if(child->getFirstChild() != NULL)
2641 {
2642 dprintf(("EnumChildWindows: Enumerate children of %x", child->getWindowHandle()));
2643 if(child->EnumChildWindows(lpfn, lParam) == FALSE)
2644 {
2645 rc = FALSE;
2646 break;
2647 }
2648 }
2649 prevchild = child;
2650 }
2651 return rc;
2652}
2653//******************************************************************************
2654//Enumerate first-level children only and check thread id
2655//******************************************************************************
2656BOOL Win32BaseWindow::EnumThreadWindows(DWORD dwThreadId, WNDENUMPROC lpfn, LPARAM lParam)
2657{
2658 Win32BaseWindow *child = 0;
2659 ULONG tid, pid;
2660 BOOL rc;
2661 HWND hwnd;
2662
2663 dprintf(("EnumThreadWindows %x %x %x", dwThreadId, lpfn, lParam));
2664
2665 for (child = (Win32BaseWindow *)getFirstChild(); child; child = (Win32BaseWindow *)child->getNextChild())
2666 {
2667 OSLibWinQueryWindowProcess(child->getOS2WindowHandle(), &pid, &tid);
2668
2669 if(dwThreadId == tid) {
2670 dprintf2(("EnumThreadWindows: Found Window %x", child->getWindowHandle()));
2671 if((rc = lpfn(child->getWindowHandle(), lParam)) == FALSE) {
2672 break;
2673 }
2674 }
2675 }
2676 return TRUE;
2677}
2678//******************************************************************************
2679//Enumerate first-level children only
2680//******************************************************************************
2681BOOL Win32BaseWindow::EnumWindows(WNDENUMPROC lpfn, LPARAM lParam)
2682{
2683 Win32BaseWindow *child = 0;
2684 BOOL rc;
2685 HWND hwnd;
2686
2687 dprintf(("EnumWindows %x %x", lpfn, lParam));
2688
2689 for (child = (Win32BaseWindow *)getFirstChild(); child; child = (Win32BaseWindow *)child->getNextChild())
2690 {
2691 hwnd = child->getWindowHandle();
2692
2693 dprintf2(("EnumWindows: Found Window %x", child->getWindowHandle()));
2694 if((rc = lpfn(child->getWindowHandle(), lParam)) == FALSE) {
2695 break;
2696 }
2697 }
2698 return TRUE;
2699}
2700//******************************************************************************
2701//******************************************************************************
2702Win32BaseWindow *Win32BaseWindow::FindWindowById(int id)
2703{
2704 for (Win32BaseWindow *child = (Win32BaseWindow *)getFirstChild(); child; child = (Win32BaseWindow *)child->getNextChild())
2705 {
2706 if (child->getWindowId() == id)
2707 {
2708 return child;
2709 }
2710 }
2711 return 0;
2712}
2713//******************************************************************************
2714//TODO:
2715//We assume (for now) that if hwndParent or hwndChildAfter are real window handles, that
2716//the current process owns them.
2717//******************************************************************************
2718HWND Win32BaseWindow::FindWindowEx(HWND hwndParent, HWND hwndChildAfter, LPSTR lpszClass, LPSTR lpszWindow,
2719 BOOL fUnicode)
2720{
2721 Win32BaseWindow *parent = GetWindowFromHandle(hwndParent);
2722 Win32BaseWindow *child = GetWindowFromHandle(hwndChildAfter);
2723
2724 if((hwndParent != OSLIB_HWND_DESKTOP && !parent) ||
2725 (hwndChildAfter != 0 && !child) ||
2726 (hwndParent == OSLIB_HWND_DESKTOP && hwndChildAfter != 0))
2727 {
2728 dprintf(("Win32BaseWindow::FindWindowEx: parent or child not found %x %x", hwndParent, hwndChildAfter));
2729 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
2730 return 0;
2731 }
2732 if(hwndParent != OSLIB_HWND_DESKTOP)
2733 {//if the current process owns the window, just do a quick search
2734 child = (Win32BaseWindow *)parent->getFirstChild();
2735 if(hwndChildAfter != 0)
2736 {
2737 while(child)
2738 {
2739 if(child->getWindowHandle() == hwndChildAfter)
2740 {
2741 child = (Win32BaseWindow *)child->getNextChild();
2742 break;
2743 }
2744 child = (Win32BaseWindow *)child->getNextChild();
2745 }
2746 }
2747 while(child)
2748 {
2749 if(child->getWindowClass()->hasClassName(lpszClass, fUnicode) &&
2750 (!lpszWindow || child->hasWindowName(lpszWindow, fUnicode)))
2751 {
2752 dprintf(("FindWindowEx: Found window %x", child->getWindowHandle()));
2753 return child->getWindowHandle();
2754 }
2755 child = (Win32BaseWindow *)child->getNextChild();
2756 }
2757 }
2758 else {
2759 Win32BaseWindow *wnd;
2760 HWND henum, hwnd;
2761
2762 henum = OSLibWinBeginEnumWindows(OSLIB_HWND_DESKTOP);
2763 hwnd = OSLibWinGetNextWindow(henum);
2764
2765 while(hwnd)
2766 {
2767 wnd = GetWindowFromOS2Handle(hwnd);
2768 if(wnd == NULL) {
2769 hwnd = OSLibWinQueryClientWindow(hwnd);
2770 if(hwnd) wnd = GetWindowFromOS2Handle(hwnd);
2771 if(!hwnd) wnd = GetWindowFromOS2FrameHandle(hwnd);
2772 }
2773
2774 if(wnd) {
2775 if(wnd->getWindowClass()->hasClassName(lpszClass, fUnicode) &&
2776 (!lpszWindow || wnd->hasWindowName(lpszWindow, fUnicode)))
2777 {
2778 OSLibWinEndEnumWindows(henum);
2779 dprintf(("FindWindowEx: Found window %x", wnd->getWindowHandle()));
2780 return wnd->getWindowHandle();
2781 }
2782 }
2783 hwnd = OSLibWinGetNextWindow(henum);
2784 }
2785 OSLibWinEndEnumWindows(henum);
2786 }
2787 SetLastError(ERROR_CANNOT_FIND_WND_CLASS); //TODO: not always correct
2788 return 0;
2789}
2790//******************************************************************************
2791//******************************************************************************
2792HWND Win32BaseWindow::GetWindow(UINT uCmd)
2793{
2794 HWND hwndRelated = 0;
2795 Win32BaseWindow *window;
2796
2797 switch(uCmd)
2798 {
2799 case GW_HWNDFIRST:
2800 if(getParent()) {
2801 window = (Win32BaseWindow *)getParent()->getFirstChild();
2802 hwndRelated = window->getWindowHandle();
2803 }
2804 break;
2805
2806 case GW_HWNDLAST:
2807 if(!getParent())
2808 {
2809 goto end;
2810 }
2811
2812 window = this;
2813 while(window->getNextChild())
2814 {
2815 window = (Win32BaseWindow *)window->getNextChild();
2816 }
2817 hwndRelated = window->getWindowHandle();
2818 break;
2819
2820 case GW_HWNDNEXT:
2821 window = (Win32BaseWindow *)getNextChild();
2822 if(window) {
2823 hwndRelated = window->getWindowHandle();
2824 }
2825 break;
2826
2827 case GW_HWNDPREV:
2828 if(!getParent())
2829 {
2830 goto end;
2831 }
2832 window = (Win32BaseWindow *)(getParent()->getFirstChild()); /* First sibling */
2833 if(window == this)
2834 {
2835 hwndRelated = 0; /* First in list */
2836 goto end;
2837 }
2838 while(window->getNextChild())
2839 {
2840 if (window->getNextChild() == this)
2841 {
2842 hwndRelated = window->getWindowHandle();
2843 goto end;
2844 }
2845 window = (Win32BaseWindow *)window->getNextChild();
2846 }
2847 break;
2848
2849 case GW_OWNER:
2850 if(getOwner()) {
2851 hwndRelated = getOwner()->getWindowHandle();
2852 }
2853 break;
2854
2855 case GW_CHILD:
2856 if(getFirstChild()) {
2857 hwndRelated = ((Win32BaseWindow *)getFirstChild())->getWindowHandle();
2858 }
2859 break;
2860 }
2861end:
2862 dprintf(("GetWindow %x %d returned %x", getWindowHandle(), uCmd, hwndRelated));
2863 return hwndRelated;
2864}
2865//******************************************************************************
2866//******************************************************************************
2867HWND Win32BaseWindow::SetActiveWindow()
2868{
2869 HWND hwndActive;
2870 Win32BaseWindow *win32wnd;
2871 ULONG magic;
2872
2873 dprintf(("SetActiveWindow %x", getWindowHandle()));
2874 hwndActive = OSLibWinSetActiveWindow(OS2HwndFrame);
2875 win32wnd = (Win32BaseWindow *)OSLibWinGetWindowULong(hwndActive, OFFSET_WIN32WNDPTR);
2876 magic = OSLibWinGetWindowULong(hwndActive, OFFSET_WIN32PM_MAGIC);
2877 if(CheckMagicDword(magic) && win32wnd)
2878 {
2879 return win32wnd->getWindowHandle();
2880 }
2881 return windowDesktop->getWindowHandle(); //pretend the desktop was active
2882}
2883//******************************************************************************
2884//WM_ENABLE is sent to hwnd, but not to it's children (as it should be)
2885//******************************************************************************
2886BOOL Win32BaseWindow::EnableWindow(BOOL fEnable)
2887{
2888 return OSLibWinEnableWindow(OS2HwndFrame, fEnable);
2889}
2890//******************************************************************************
2891//******************************************************************************
2892BOOL Win32BaseWindow::CloseWindow()
2893{
2894 return OSLibWinMinimizeWindow(OS2HwndFrame);
2895}
2896//******************************************************************************
2897//******************************************************************************
2898HWND Win32BaseWindow::GetActiveWindow()
2899{
2900 HWND hwndActive;
2901 Win32BaseWindow *win32wnd;
2902 ULONG magic;
2903
2904 hwndActive = OSLibWinQueryActiveWindow();
2905
2906 return OS2ToWin32Handle(hwndActive);
2907}
2908//******************************************************************************
2909//******************************************************************************
2910BOOL Win32BaseWindow::IsWindowEnabled()
2911{
2912 return OSLibWinIsWindowEnabled(OS2HwndFrame);
2913}
2914//******************************************************************************
2915//******************************************************************************
2916BOOL Win32BaseWindow::IsWindowVisible()
2917{
2918#if 1
2919 return (dwStyle & WS_VISIBLE) == WS_VISIBLE;
2920#else
2921 return OSLibWinIsWindowVisible(OS2HwndFrame);
2922#endif
2923}
2924//******************************************************************************
2925//******************************************************************************
2926BOOL Win32BaseWindow::hasWindowName(LPSTR wndname, BOOL fUnicode)
2927{
2928 INT len = GetWindowTextLength();
2929 BOOL res;
2930
2931 if (wndname == NULL)
2932 return (len == 0);
2933
2934 len++;
2935 if (fUnicode)
2936 {
2937 WCHAR *text = (WCHAR*)malloc(len*sizeof(WCHAR));
2938
2939 GetWindowTextW(text,len);
2940 res = (lstrcmpW(text,(LPWSTR)wndname) == 0);
2941 free(text);
2942 } else
2943 {
2944 CHAR *text = (CHAR*)malloc(len*sizeof(CHAR));
2945
2946 GetWindowTextA(text,len);
2947 res = (strcmp(text,wndname) == 0);
2948 free(text);
2949 }
2950
2951 return res;
2952}
2953//******************************************************************************
2954//******************************************************************************
2955CHAR *Win32BaseWindow::getWindowNamePtrA()
2956{
2957 INT len = GetWindowTextLength();
2958 CHAR *text;
2959
2960 if (len == 0) return NULL;
2961 len++;
2962 text = (CHAR*)malloc(len*sizeof(CHAR));
2963 GetWindowTextA(text,len);
2964
2965 return text;
2966}
2967//******************************************************************************
2968//******************************************************************************
2969WCHAR *Win32BaseWindow::getWindowNamePtrW()
2970{
2971 INT len = GetWindowTextLength();
2972 WCHAR *text;
2973
2974 if (len == 0) return NULL;
2975 len++;
2976 text = (WCHAR*)malloc(len*sizeof(WCHAR));
2977 GetWindowTextW(text,len);
2978
2979 return text;
2980}
2981//******************************************************************************
2982//******************************************************************************
2983VOID Win32BaseWindow::freeWindowNamePtr(PVOID namePtr)
2984{
2985 if (namePtr) free(namePtr);
2986}
2987//******************************************************************************
2988//******************************************************************************
2989int Win32BaseWindow::GetWindowTextLength()
2990{
2991 return SendInternalMessageA(WM_GETTEXTLENGTH,0,0);
2992}
2993//******************************************************************************
2994//******************************************************************************
2995int Win32BaseWindow::GetWindowTextA(LPSTR lpsz, int cch)
2996{
2997 return SendInternalMessageA(WM_GETTEXT,(WPARAM)cch,(LPARAM)lpsz);
2998}
2999//******************************************************************************
3000//******************************************************************************
3001int Win32BaseWindow::GetWindowTextW(LPWSTR lpsz, int cch)
3002{
3003 return SendInternalMessageW(WM_GETTEXT,(WPARAM)cch,(LPARAM)lpsz);
3004}
3005//******************************************************************************
3006//******************************************************************************
3007BOOL Win32BaseWindow::SetWindowTextA(LPSTR lpsz)
3008{
3009 return SendInternalMessageA(WM_SETTEXT,0,(LPARAM)lpsz);
3010}
3011//******************************************************************************
3012//******************************************************************************
3013BOOL Win32BaseWindow::SetWindowTextW(LPWSTR lpsz)
3014{
3015 return SendInternalMessageW(WM_SETTEXT,0,(LPARAM)lpsz);
3016}
3017//******************************************************************************
3018//******************************************************************************
3019LONG Win32BaseWindow::SetWindowLongA(int index, ULONG value, BOOL fUnicode)
3020{
3021 LONG oldval;
3022
3023 dprintf2(("SetWindowLong%c %x %d %x", (fUnicode) ? 'W' : 'A', getWindowHandle(), index, value));
3024 switch(index) {
3025 case GWL_EXSTYLE:
3026 {
3027 STYLESTRUCT ss;
3028
3029 if(dwExStyle == value)
3030 return value;
3031
3032 ss.styleOld = dwExStyle;
3033 ss.styleNew = value;
3034 dprintf(("SetWindowLong GWL_EXSTYLE %x old %x new style %x", getWindowHandle(), dwExStyle, value));
3035 SendInternalMessageA(WM_STYLECHANGING,GWL_EXSTYLE,(LPARAM)&ss);
3036 setExStyle(ss.styleNew);
3037 SendInternalMessageA(WM_STYLECHANGED,GWL_EXSTYLE,(LPARAM)&ss);
3038 return ss.styleOld;
3039 }
3040 case GWL_STYLE:
3041 {
3042 STYLESTRUCT ss;
3043
3044 if(dwStyle == value)
3045 return value;
3046
3047 value &= ~(WS_VISIBLE | WS_CHILD); /* Some bits can't be changed this way (WINE) */
3048 ss.styleOld = getStyle();
3049 ss.styleNew = value | (ss.styleOld & (WS_VISIBLE | WS_CHILD));
3050 dprintf(("SetWindowLong GWL_STYLE %x old %x new style %x", getWindowHandle(), ss.styleOld, ss.styleNew));
3051 SendInternalMessageA(WM_STYLECHANGING,GWL_STYLE,(LPARAM)&ss);
3052 setStyle(ss.styleNew);
3053 SendInternalMessageA(WM_STYLECHANGED,GWL_STYLE,(LPARAM)&ss);
3054//// OSLibSetWindowStyle(getOS2FrameWindowHandle(), getStyle(), getExStyle(),
3055//// windowClass->getStyle() & CS_SAVEBITS);
3056#ifdef DEBUG
3057 PrintWindowStyle(ss.styleNew, 0);
3058#endif
3059 return ss.styleOld;
3060 }
3061 case GWL_WNDPROC:
3062 oldval = (LONG)WINPROC_GetProc(win32wndproc, (fUnicode) ? WIN_PROC_32W : WIN_PROC_32A);
3063 WINPROC_SetProc((HWINDOWPROC *)&win32wndproc, (WNDPROC)value, WINPROC_GetProcType(win32wndproc), WIN_PROC_WINDOW);
3064 return oldval;
3065
3066 case GWL_HINSTANCE:
3067 oldval = hInstance;
3068 hInstance = value;
3069 return oldval;
3070
3071 case GWL_HWNDPARENT:
3072 return SetParent((HWND)value);
3073
3074 case GWL_ID:
3075 oldval = getWindowId();
3076 setWindowId(value);
3077 return oldval;
3078
3079 case GWL_USERDATA:
3080 oldval = userData;
3081 userData = value;
3082 return oldval;
3083
3084 default:
3085 if(index >= 0 && index/4 < nrUserWindowLong)
3086 {
3087 oldval = userWindowLong[index/4];
3088 userWindowLong[index/4] = value;
3089 return oldval;
3090 }
3091 SetLastError(ERROR_INVALID_PARAMETER);
3092 return 0;
3093 }
3094}
3095//******************************************************************************
3096//******************************************************************************
3097ULONG Win32BaseWindow::GetWindowLongA(int index, BOOL fUnicode)
3098{
3099 ULONG value;
3100
3101 switch(index) {
3102 case GWL_EXSTYLE:
3103 value = dwExStyle;
3104 break;
3105 case GWL_STYLE:
3106 value = dwStyle;
3107 break;
3108 case GWL_WNDPROC:
3109 value = (LONG)WINPROC_GetProc(win32wndproc, (fUnicode) ? WIN_PROC_32W : WIN_PROC_32A);
3110 break;
3111 case GWL_HINSTANCE:
3112 value = hInstance;
3113 break;
3114 case GWL_HWNDPARENT:
3115 if(getParent()) {
3116 value = getParent()->getWindowHandle();
3117 }
3118 else value = 0;
3119 break;
3120 case GWL_ID:
3121 value = getWindowId();
3122 break;
3123 case GWL_USERDATA:
3124 value = userData;
3125 break;
3126 default:
3127 if(index >= 0 && index/4 < nrUserWindowLong)
3128 {
3129 value = userWindowLong[index/4];
3130 break;
3131 }
3132 SetLastError(ERROR_INVALID_PARAMETER);
3133 return 0;
3134 }
3135 dprintf2(("GetWindowLongA %x %d %x", getWindowHandle(), index, value));
3136 return value;
3137}
3138//******************************************************************************
3139//******************************************************************************
3140WORD Win32BaseWindow::SetWindowWord(int index, WORD value)
3141{
3142 WORD oldval;
3143
3144 if(index >= 0 && index/4 < nrUserWindowLong)
3145 {
3146 oldval = ((WORD *)userWindowLong)[index/2];
3147 ((WORD *)userWindowLong)[index/2] = value;
3148 return oldval;
3149 }
3150 SetLastError(ERROR_INVALID_PARAMETER);
3151 return 0;
3152}
3153//******************************************************************************
3154//******************************************************************************
3155WORD Win32BaseWindow::GetWindowWord(int index)
3156{
3157 if(index >= 0 && index/4 < nrUserWindowLong)
3158 {
3159 return ((WORD *)userWindowLong)[index/2];
3160 }
3161 SetLastError(ERROR_INVALID_PARAMETER);
3162 return 0;
3163}
3164//******************************************************************************
3165//******************************************************************************
3166void Win32BaseWindow::setWindowId(DWORD id)
3167{
3168 dwIDMenu = id;
3169}
3170//******************************************************************************
3171//******************************************************************************
3172Win32BaseWindow *Win32BaseWindow::GetWindowFromHandle(HWND hwnd)
3173{
3174 Win32BaseWindow *window;
3175
3176 if(HwGetWindowHandleData(hwnd, (DWORD *)&window) == TRUE) {
3177 return window;
3178 }
3179// dprintf2(("Win32BaseWindow::GetWindowFromHandle: not a win32 window %x", hwnd));
3180 return NULL;
3181}
3182//******************************************************************************
3183//******************************************************************************
3184Win32BaseWindow *Win32BaseWindow::GetWindowFromOS2Handle(HWND hwnd)
3185{
3186 Win32BaseWindow *win32wnd;
3187 DWORD magic;
3188
3189 if(hwnd == OSLIB_HWND_DESKTOP)
3190 {
3191 return windowDesktop;
3192 }
3193
3194 win32wnd = (Win32BaseWindow *)OSLibWinGetWindowULong(hwnd, OFFSET_WIN32WNDPTR);
3195 magic = OSLibWinGetWindowULong(hwnd, OFFSET_WIN32PM_MAGIC);
3196
3197 if(win32wnd && CheckMagicDword(magic)) {
3198 return win32wnd;
3199 }
3200// dprintf2(("Win32BaseWindow::GetWindowFromOS2Handle: not an Odin os2 window %x", hwnd));
3201 return 0;
3202}
3203//******************************************************************************
3204//******************************************************************************
3205Win32BaseWindow *Win32BaseWindow::GetWindowFromOS2FrameHandle(HWND hwnd)
3206{
3207 return GetWindowFromOS2Handle(OSLibWinWindowFromID(hwnd,OSLIB_FID_CLIENT));
3208}
3209//******************************************************************************
3210//******************************************************************************
3211HWND Win32BaseWindow::Win32ToOS2Handle(HWND hwnd)
3212{
3213 Win32BaseWindow *window = GetWindowFromHandle(hwnd);
3214
3215 if(window) {
3216 return window->getOS2WindowHandle();
3217 }
3218// dprintf2(("Win32BaseWindow::Win32ToOS2Handle: not a win32 window %x", hwnd));
3219 return hwnd;
3220}
3221//******************************************************************************
3222//******************************************************************************
3223HWND Win32BaseWindow::Win32ToOS2FrameHandle(HWND hwnd)
3224{
3225 Win32BaseWindow *window = GetWindowFromHandle(hwnd);
3226
3227 if(window) {
3228 return window->getOS2FrameWindowHandle();
3229 }
3230// dprintf2(("Win32BaseWindow::Win32ToOS2FrameHandle: not a win32 window %x", hwnd));
3231 return hwnd;
3232}
3233//******************************************************************************
3234//******************************************************************************
3235HWND Win32BaseWindow::OS2ToWin32Handle(HWND hwnd)
3236{
3237 Win32BaseWindow *window = GetWindowFromOS2Handle(hwnd);
3238
3239 if(window) {
3240 return window->getWindowHandle();
3241 }
3242 window = GetWindowFromOS2FrameHandle(hwnd);
3243 if(window) {
3244 return window->getWindowHandle();
3245 }
3246// dprintf2(("Win32BaseWindow::OS2ToWin32Handle: not a win32 window %x", hwnd));
3247 return 0;
3248// else return hwnd; //OS/2 window handle
3249}
3250//******************************************************************************
3251// GetNextDlgTabItem32 (USER32.276)
3252//******************************************************************************
3253HWND Win32BaseWindow::getNextDlgTabItem(HWND hwndCtrl, BOOL fPrevious)
3254{
3255 Win32BaseWindow *child, *nextchild, *lastchild;
3256 HWND retvalue;
3257
3258 if (hwndCtrl)
3259 {
3260 child = GetWindowFromHandle(hwndCtrl);
3261 if (!child)
3262 {
3263 retvalue = 0;
3264 goto END;
3265 }
3266 /* Make sure hwndCtrl is a top-level child */
3267 while ((child->getStyle() & WS_CHILD) && (child->getParent() != this))
3268 {
3269 child = child->getParent();
3270 if(child == NULL) break;
3271 }
3272
3273 if (!child || (child->getParent() != this))
3274 {
3275 retvalue = 0;
3276 goto END;
3277 }
3278 }
3279 else
3280 {
3281 /* No ctrl specified -> start from the beginning */
3282 child = (Win32BaseWindow *)getFirstChild();
3283 if (!child)
3284 {
3285 retvalue = 0;
3286 goto END;
3287 }
3288
3289 if (!fPrevious)
3290 {
3291 while (child->getNextChild())
3292 {
3293 child = (Win32BaseWindow *)child->getNextChild();
3294 }
3295 }
3296 }
3297
3298 lastchild = child;
3299 nextchild = (Win32BaseWindow *)child->getNextChild();
3300 while (TRUE)
3301 {
3302 if (!nextchild) nextchild = (Win32BaseWindow *)getFirstChild();
3303
3304 if (child == nextchild) break;
3305
3306 if ((nextchild->getStyle() & WS_TABSTOP) && (nextchild->getStyle() & WS_VISIBLE) &&
3307 !(nextchild->getStyle() & WS_DISABLED))
3308 {
3309 lastchild = nextchild;
3310 if (!fPrevious) break;
3311 }
3312 nextchild = (Win32BaseWindow *)nextchild->getNextChild();
3313 }
3314 retvalue = lastchild->getWindowHandle();
3315
3316END:
3317 return retvalue;
3318}
3319//******************************************************************************
3320//******************************************************************************
3321HWND Win32BaseWindow::getNextDlgGroupItem(HWND hwndCtrl, BOOL fPrevious)
3322{
3323 Win32BaseWindow *child, *nextchild, *lastchild;
3324 HWND retvalue;
3325
3326 if (hwndCtrl)
3327 {
3328 child = GetWindowFromHandle(hwndCtrl);
3329 if (!child)
3330 {
3331 retvalue = 0;
3332 goto END;
3333 }
3334 /* Make sure hwndCtrl is a top-level child */
3335 while ((child->getStyle() & WS_CHILD) && (child->getParent() != this))
3336 {
3337 child = child->getParent();
3338 if(child == NULL) break;
3339 }
3340
3341 if (!child || (child->getParent() != this))
3342 {
3343 retvalue = 0;
3344 goto END;
3345 }
3346 }
3347 else
3348 {
3349 /* No ctrl specified -> start from the beginning */
3350 child = (Win32BaseWindow *)getFirstChild();
3351 if (!child)
3352 {
3353 retvalue = 0;
3354 goto END;
3355 }
3356
3357 if (fPrevious)
3358 {
3359 while (child->getNextChild())
3360 {
3361 child = (Win32BaseWindow *)child->getNextChild();
3362 }
3363 }
3364 }
3365
3366 lastchild = child;
3367 nextchild = (Win32BaseWindow *)child->getNextChild();
3368 while (TRUE)
3369 {
3370 if (!nextchild || (nextchild->getStyle() & WS_GROUP))
3371 {
3372 /* Wrap-around to the beginning of the group */
3373 Win32BaseWindow *pWndTemp;
3374
3375 nextchild = (Win32BaseWindow *)getFirstChild();
3376
3377 for(pWndTemp = nextchild;pWndTemp;pWndTemp = (Win32BaseWindow *)pWndTemp->getNextChild())
3378 {
3379 if (pWndTemp->getStyle() & WS_GROUP)
3380 nextchild = pWndTemp;
3381
3382 if (pWndTemp == child)
3383 break;
3384 }
3385
3386 }
3387 if (nextchild == child)
3388 break;
3389
3390 if ((nextchild->getStyle() & WS_VISIBLE) && !(nextchild->getStyle() & WS_DISABLED))
3391 {
3392 lastchild = nextchild;
3393
3394 if (!fPrevious)
3395 break;
3396 }
3397
3398 nextchild = (Win32BaseWindow *)nextchild->getNextChild();
3399 }
3400 retvalue = lastchild->getWindowHandle();
3401END:
3402 return retvalue;
3403}
3404//******************************************************************************
3405//******************************************************************************
3406#ifdef DEBUG
3407void PrintWindowStyle(DWORD dwStyle, DWORD dwExStyle)
3408{
3409 char style[256] = "";
3410 char exstyle[256] = "";
3411
3412 /* Window styles */
3413 if(dwStyle & WS_CHILD)
3414 strcat(style, "WS_CHILD ");
3415 if(dwStyle & WS_POPUP)
3416 strcat(style, "WS_POPUP ");
3417 if(dwStyle & WS_VISIBLE)
3418 strcat(style, "WS_VISIBLE ");
3419 if(dwStyle & WS_DISABLED)
3420 strcat(style, "WS_DISABLED ");
3421 if(dwStyle & WS_CLIPSIBLINGS)
3422 strcat(style, "WS_CLIPSIBLINGS ");
3423 if(dwStyle & WS_CLIPCHILDREN)
3424 strcat(style, "WS_CLIPCHILDREN ");
3425 if(dwStyle & WS_MAXIMIZE)
3426 strcat(style, "WS_MAXIMIZE ");
3427 if(dwStyle & WS_MINIMIZE)
3428 strcat(style, "WS_MINIMIZE ");
3429 if(dwStyle & WS_GROUP)
3430 strcat(style, "WS_GROUP ");
3431 if(dwStyle & WS_TABSTOP)
3432 strcat(style, "WS_TABSTOP ");
3433
3434 if((dwStyle & WS_CAPTION) == WS_CAPTION)
3435 strcat(style, "WS_CAPTION ");
3436 if(dwStyle & WS_DLGFRAME)
3437 strcat(style, "WS_DLGFRAME ");
3438 if(dwStyle & WS_BORDER)
3439 strcat(style, "WS_BORDER ");
3440
3441 if(dwStyle & WS_VSCROLL)
3442 strcat(style, "WS_VSCROLL ");
3443 if(dwStyle & WS_HSCROLL)
3444 strcat(style, "WS_HSCROLL ");
3445 if(dwStyle & WS_SYSMENU)
3446 strcat(style, "WS_SYSMENU ");
3447 if(dwStyle & WS_THICKFRAME)
3448 strcat(style, "WS_THICKFRAME ");
3449 if(dwStyle & WS_MINIMIZEBOX)
3450 strcat(style, "WS_MINIMIZEBOX ");
3451 if(dwStyle & WS_MAXIMIZEBOX)
3452 strcat(style, "WS_MAXIMIZEBOX ");
3453
3454 if(dwExStyle & WS_EX_DLGMODALFRAME)
3455 strcat(exstyle, "WS_EX_DLGMODALFRAME ");
3456 if(dwExStyle & WS_EX_ACCEPTFILES)
3457 strcat(exstyle, "WS_EX_ACCEPTFILES ");
3458 if(dwExStyle & WS_EX_NOPARENTNOTIFY)
3459 strcat(exstyle, "WS_EX_NOPARENTNOTIFY ");
3460 if(dwExStyle & WS_EX_TOPMOST)
3461 strcat(exstyle, "WS_EX_TOPMOST ");
3462 if(dwExStyle & WS_EX_TRANSPARENT)
3463 strcat(exstyle, "WS_EX_TRANSPARENT ");
3464
3465 if(dwExStyle & WS_EX_MDICHILD)
3466 strcat(exstyle, "WS_EX_MDICHILD ");
3467 if(dwExStyle & WS_EX_TOOLWINDOW)
3468 strcat(exstyle, "WS_EX_TOOLWINDOW ");
3469 if(dwExStyle & WS_EX_WINDOWEDGE)
3470 strcat(exstyle, "WS_EX_WINDOWEDGE ");
3471 if(dwExStyle & WS_EX_CLIENTEDGE)
3472 strcat(exstyle, "WS_EX_CLIENTEDGE ");
3473 if(dwExStyle & WS_EX_CONTEXTHELP)
3474 strcat(exstyle, "WS_EX_CONTEXTHELP ");
3475 if(dwExStyle & WS_EX_RIGHT)
3476 strcat(exstyle, "WS_EX_RIGHT ");
3477 if(dwExStyle & WS_EX_LEFT)
3478 strcat(exstyle, "WS_EX_LEFT ");
3479 if(dwExStyle & WS_EX_RTLREADING)
3480 strcat(exstyle, "WS_EX_RTLREADING ");
3481 if(dwExStyle & WS_EX_LTRREADING)
3482 strcat(exstyle, "WS_EX_LTRREADING ");
3483 if(dwExStyle & WS_EX_LEFTSCROLLBAR)
3484 strcat(exstyle, "WS_EX_LEFTSCROLLBAR ");
3485 if(dwExStyle & WS_EX_RIGHTSCROLLBAR)
3486 strcat(exstyle, "WS_EX_RIGHTSCROLLBAR ");
3487 if(dwExStyle & WS_EX_CONTROLPARENT)
3488 strcat(exstyle, "WS_EX_CONTROLPARENT ");
3489 if(dwExStyle & WS_EX_STATICEDGE)
3490 strcat(exstyle, "WS_EX_STATICEDGE ");
3491 if(dwExStyle & WS_EX_APPWINDOW)
3492 strcat(exstyle, "WS_EX_APPWINDOW ");
3493
3494 dprintf(("Window style: %x %s", dwStyle, style));
3495 dprintf(("Window exStyle: %x %s (FS = %x)", dwExStyle, exstyle, GetFS()));
3496}
3497#endif
3498//******************************************************************************
3499//******************************************************************************
3500
3501GenericObject *Win32BaseWindow::windows = NULL;
Note: See TracBrowser for help on using the repository browser.