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

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

Rewrote some message apis + WM_WINDOWPOSCHANGED fix

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