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

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

MDI fix, extra message support etc

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