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

Last change on this file since 4524 was 4524, checked in by sandervl, 25 years ago

GetWindowText(Lenght)A/W fixes for windows belonging to different processes

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