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

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

EB's window style fixes

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