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

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

Lots of changes/fixes

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