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

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

Scrollbar changes

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