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

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

Only subclass frame when they have either a 3d border or *only* the WS_BORDER borderstyle

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