source: trunk/src/user32/new/win32wnd.cpp@ 715

Last change on this file since 715 was 715, checked in by dengert, 26 years ago

window creation, positioning, sizing

File size: 65.8 KB
Line 
1/* $Id: win32wnd.cpp,v 1.31 1999-08-27 17:50:56 dengert Exp $ */
2/*
3 * Win32 Window Code for OS/2
4 *
5 *
6 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
7 * Copyright 1999 Daniela Engert (dani@ngrt.de)
8 *
9 * Parts based on Wine Windows code (windows\win.c)
10 *
11 * Copyright 1993, 1994 Alexandre Julliard
12 *
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 <handlemanager.h>
25#include <win32wnd.h>
26#include <spy.h>
27#include "wndmsg.h"
28#include "hooks.h"
29#include <oslibwin.h>
30#include <oslibutil.h>
31#include <oslibgdi.h>
32#include <oslibres.h>
33#include <winres.h>
34#include "syscolor.h"
35
36#define HAS_DLGFRAME(style,exStyle) \
37 (((exStyle) & WS_EX_DLGMODALFRAME) || \
38 (((style) & WS_DLGFRAME) && !((style) & WS_BORDER)))
39
40#define HAS_THICKFRAME(style) \
41 (((style) & WS_THICKFRAME) && \
42 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
43
44#define HAS_BORDER(style, exStyle) \
45 ((style & WS_BORDER) || HAS_THICKFRAME(style) || HAS_DLGFRAME(style,exStyle))
46
47#define IS_OVERLAPPED(style) \
48 !(style & (WS_CHILD | WS_POPUP))
49
50//******************************************************************************
51//******************************************************************************
52Win32Window::Win32Window(DWORD objType) : GenericObject(&windows, objType)
53{
54 Init();
55}
56//******************************************************************************
57//******************************************************************************
58Win32Window::Win32Window(CREATESTRUCTA *lpCreateStructA, ATOM classAtom, BOOL isUnicode)
59 : GenericObject(&windows, OBJTYPE_WINDOW), ChildWindow()
60{
61 Init();
62 this->isUnicode = isUnicode;
63 CreateWindowExA(lpCreateStructA, classAtom);
64}
65//******************************************************************************
66//******************************************************************************
67void Win32Window::Init()
68{
69 isUnicode = FALSE;
70 fCreated = FALSE;
71 fFirstShow = TRUE;
72
73 memset(windowNameA, 0, MAX_WINDOW_NAMELENGTH);
74 memset(windowNameW, 0, MAX_WINDOW_NAMELENGTH*sizeof(WCHAR));
75 wndNameLength = 0;
76
77 userWindowLong = NULL;;
78 nrUserWindowLong = 0;
79
80 magic = WIN32PM_MAGIC;
81 OS2Hwnd = 0;
82 OS2HwndFrame = 0;
83 OS2HwndMenu = 0;
84 Win32Hwnd = 0;
85
86 if(HMHandleAllocate(&Win32Hwnd, (ULONG)this) != 0)
87 {
88 dprintf(("Win32Window::Init HMHandleAllocate failed!!"));
89 DebugInt3();
90 }
91 Win32Hwnd &= 0xFFFF;
92 Win32Hwnd |= 0x68000000;
93
94 posx = posy = 0;
95 width = height = 0;
96
97 dwExStyle = 0;
98 dwStyle = 0;
99 win32wndproc = 0;
100 hInstance = 0;
101 windowId = 0xFFFFFFFF; //default = -1
102 userData = 0;
103
104 hwndLinkAfter = HWND_BOTTOM;
105 flags = 0;
106 isIcon = FALSE;
107 lastHitTestVal = 0;
108 owner = NULL;
109 windowClass = 0;
110
111 acceltableResource = NULL;
112 menuResource = NULL;
113 iconResource = NULL;
114}
115//******************************************************************************
116//todo get rid of resources (menu, accel, icon etc)
117//******************************************************************************
118Win32Window::~Win32Window()
119{
120 OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, 0);
121 OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, 0);
122
123 if(Win32Hwnd)
124 HMHandleFree(Win32Hwnd & 0xFFFF);
125 if(userWindowLong)
126 free(userWindowLong);
127}
128//******************************************************************************
129//******************************************************************************
130BOOL Win32Window::isChild()
131{
132 return (dwStyle & WS_CHILD) != 0;
133}
134//******************************************************************************
135//******************************************************************************
136BOOL Win32Window::CreateWindowExA(CREATESTRUCTA *cs, ATOM classAtom)
137{
138 char buffer[256];
139 INT sw = SW_SHOW;
140 POINT maxSize, maxPos, minTrack, maxTrack;
141
142 SetLastError(0);
143
144 /* Find the parent window */
145 if (cs->hwndParent)
146 {
147 Win32Window *window = GetWindowFromHandle(cs->hwndParent);
148 if(!window) {
149 dprintf(("Bad parent %04x\n", cs->hwndParent ));
150 SetLastError(ERROR_INVALID_PARAMETER);
151 return FALSE;
152 }
153 /* Make sure parent is valid */
154 if (!window->IsWindow() )
155 {
156 dprintf(("Bad parent %04x\n", cs->hwndParent ));
157 SetLastError(ERROR_INVALID_PARAMETER);
158 return FALSE;
159 }
160 }
161 else
162 if ((cs->style & WS_CHILD) && !(cs->style & WS_POPUP)) {
163 dprintf(("No parent for child window\n" ));
164 SetLastError(ERROR_INVALID_PARAMETER);
165 return FALSE; /* WS_CHILD needs a parent, but WS_POPUP doesn't */
166 }
167
168 /* Find the window class */
169 windowClass = Win32WndClass::FindClass(cs->hInstance, (LPSTR)classAtom);
170 if (!windowClass)
171 {
172 GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) );
173 dprintf(("Bad class '%s'\n", buffer ));
174 return 0;
175 }
176
177 /* Fix the lpszClass field: from existing programs, it seems ok to call a CreateWindowXXX
178 * with an atom as the class name, put some programs expect to have a *REAL* string in
179 * lpszClass when the CREATESTRUCT is sent with WM_CREATE
180 */
181 if (!HIWORD(cs->lpszClass) ) {
182 if (isUnicode) {
183 GlobalGetAtomNameW( classAtom, (LPWSTR)buffer, sizeof(buffer) );
184 }
185 else {
186 GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) );
187 }
188 cs->lpszClass = buffer;
189 }
190
191 /* Fix the coordinates */
192 if (cs->x == CW_USEDEFAULT || cs->x == CW_USEDEFAULT16)
193 {
194// PDB *pdb = PROCESS_Current();
195
196 /* Never believe Microsoft's documentation... CreateWindowEx doc says
197 * that if an overlapped window is created with WS_VISIBLE style bit
198 * set and the x parameter is set to CW_USEDEFAULT, the system ignores
199 * the y parameter. However, disassembling NT implementation (WIN32K.SYS)
200 * reveals that
201 *
202 * 1) not only if checks for CW_USEDEFAULT but also for CW_USEDEFAULT16
203 * 2) it does not ignore the y parameter as the docs claim; instead, it
204 * uses it as second parameter to ShowWindow() unless y is either
205 * CW_USEDEFAULT or CW_USEDEFAULT16.
206 *
207 * The fact that we didn't do 2) caused bogus windows pop up when wine
208 * was running apps that were using this obscure feature. Example -
209 * calc.exe that comes with Win98 (only Win98, it's different from
210 * the one that comes with Win95 and NT)
211 */
212 if (cs->y != CW_USEDEFAULT && cs->y != CW_USEDEFAULT16) sw = cs->y;
213
214 /* We have saved cs->y, now we can trash it */
215#if 0
216 if ( !(cs->style & (WS_CHILD | WS_POPUP))
217 && (pdb->env_db->startup_info->dwFlags & STARTF_USEPOSITION) )
218 {
219 cs->x = pdb->env_db->startup_info->dwX;
220 cs->y = pdb->env_db->startup_info->dwY;
221 }
222#endif
223 cs->x = 0;
224 cs->y = 0;
225// }
226 }
227 if (cs->cx == CW_USEDEFAULT || cs->cx == CW_USEDEFAULT16)
228 {
229#if 0
230 PDB *pdb = PROCESS_Current();
231 if ( !(cs->style & (WS_CHILD | WS_POPUP))
232 && (pdb->env_db->startup_info->dwFlags & STARTF_USESIZE) )
233 {
234 cs->cx = pdb->env_db->startup_info->dwXSize;
235 cs->cy = pdb->env_db->startup_info->dwYSize;
236 }
237 else
238 {
239#endif
240 cs->cx = 600; /* FIXME */
241 cs->cy = 400;
242// }
243 }
244
245 if (cs->x < 0) cs->x = 0;
246 if (cs->y < 0) cs->y = 0;
247
248 //Allocate window words
249 nrUserWindowLong = windowClass->getExtraWndWords();
250 if(nrUserWindowLong) {
251 userWindowLong = (ULONG *)malloc(nrUserWindowLong);
252 memset(userWindowLong, 0, nrUserWindowLong);
253 }
254
255 if ((cs->style & WS_CHILD) && cs->hwndParent)
256 {
257 SetParent(cs->hwndParent);
258 owner = GetWindowFromHandle(cs->hwndParent);
259 if(owner == NULL)
260 {
261 dprintf(("HMHandleTranslateToOS2 couldn't find owner window %x!!!", cs->hwndParent));
262 return FALSE;
263 }
264 }
265 else
266 {
267 if (!cs->hwndParent) {
268 owner = NULL;
269 }
270 else
271 {
272 owner = GetWindowFromHandle(cs->hwndParent);
273 if(owner == NULL)
274 {
275 dprintf(("HMHandleTranslateToOS2 couldn't find owner window %x!!!", cs->hwndParent));
276 return FALSE;
277 }
278 }
279 }
280
281 setWindowProc(windowClass->getWindowProc());
282 hInstance = cs->hInstance;
283 dwStyle = cs->style & ~WS_VISIBLE;
284 dwExStyle = cs->dwExStyle;
285
286 hwndLinkAfter = ((cs->style & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
287 ? HWND_BOTTOM : HWND_TOP;
288
289#if 0
290//TODO
291 /* Call the WH_CBT hook */
292
293 if (HOOK_IsHooked( WH_CBT ))
294 {
295 CBT_CREATEWNDA cbtc;
296 LRESULT ret;
297
298 cbtc.lpcs = cs;
299 cbtc.hwndInsertAfter = hwndLinkAfter;
300 ret = unicode ? HOOK_CallHooksW(WH_CBT, HCBT_CREATEWND, Win32Hwnd, (LPARAM)&cbtc)
301 : HOOK_CallHooksA(WH_CBT, HCBT_CREATEWND, Win32Hwnd, (LPARAM)&cbtc);
302 if (ret)
303 {
304 TRACE_(win)("CBT-hook returned 0\n");
305 wndPtr->pDriver->pFinalize(wndPtr);
306 retvalue = 0;
307 goto end;
308 }
309 }
310#endif
311
312 /* Increment class window counter */
313 windowClass->IncreaseWindowCount();
314
315 /* Correct the window style */
316 if (!(cs->style & WS_CHILD))
317 {
318 dwStyle |= WS_CLIPSIBLINGS;
319 if (!(cs->style & WS_POPUP))
320 {
321 dwStyle |= WS_CAPTION;
322 flags |= WIN_NEED_SIZE;
323 }
324 }
325 if (cs->dwExStyle & WS_EX_DLGMODALFRAME) dwStyle &= ~WS_THICKFRAME;
326
327 //TODO?
328#if 0
329 /* Get class or window DC if needed */
330 if (classPtr->style & CS_OWNDC) dce = DCE_AllocDCE(hwnd,DCE_WINDOW_DC);
331 else if (classPtr->style & CS_CLASSDC) wndPtr->dce = classPtr->dce;
332 else wndPtr->dce = NULL;
333#endif
334
335 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
336 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
337 {
338 GetMinMaxInfo(&maxSize, &maxPos, &minTrack, &maxTrack);
339 if (maxSize.x < cs->cx) cs->cx = maxSize.x;
340 if (maxSize.y < cs->cy) cs->cy = maxSize.y;
341 if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
342 if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
343 }
344
345 if(cs->style & WS_CHILD)
346 {
347 if(cs->cx < 0) cs->cx = 0;
348 if(cs->cy < 0) cs->cy = 0;
349 }
350 else
351 {
352 if (cs->cx <= 0) cs->cx = 1;
353 if (cs->cy <= 0) cs->cy = 1;
354 }
355
356 rectWindow.left = cs->x;
357 rectWindow.top = cs->y;
358 rectWindow.right = cs->x + cs->cx;
359 rectWindow.bottom = cs->y + cs->cy;
360 rectClient = rectWindow;
361
362 DWORD dwOSWinStyle, dwOSFrameStyle;
363
364 OSLibWinConvertStyle(cs->style, cs->dwExStyle, &dwOSWinStyle, &dwOSFrameStyle);
365
366 //TODO: Test
367#if 1
368 if(cs->style & WS_CHILD) {
369 dwOSFrameStyle = 0;
370 }
371#endif
372
373 OS2Hwnd = OSLibWinCreateWindow((getParent()) ? getParent()->getOS2WindowHandle() : OSLIB_HWND_DESKTOP,
374 dwOSWinStyle, dwOSFrameStyle, (char *)cs->lpszName,
375 (owner) ? owner->getOS2WindowHandle() : OSLIB_HWND_DESKTOP,
376 (hwndLinkAfter == HWND_BOTTOM) ? TRUE : FALSE,
377 &OS2HwndFrame);
378
379 if(OS2Hwnd == 0) {
380 dprintf(("Window creation failed!!"));
381 return FALSE;
382 }
383
384 if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, (ULONG)this) == FALSE) {
385 dprintf(("WM_CREATE: WinSetWindowULong %X failed!!", OS2Hwnd));
386 return FALSE;
387 }
388 if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, WIN32PM_MAGIC) == FALSE) {
389 dprintf(("WM_CREATE: WinSetWindowULong2 %X failed!!", OS2Hwnd));
390 return FALSE;
391 }
392#if 0
393 if(OS2Hwnd != OS2HwndFrame) {
394 if(OSLibWinSetWindowULong(OS2HwndFrame, OFFSET_WIN32WNDPTR, (ULONG)this) == FALSE) {
395 dprintf(("WM_CREATE: WinSetWindowULong %X failed!!", OS2HwndFrame));
396 return FALSE;
397 }
398 if(OSLibWinSetWindowULong(OS2HwndFrame, OFFSET_WIN32PM_MAGIC, WIN32PM_MAGIC) == FALSE) {
399 dprintf(("WM_CREATE: WinSetWindowULong2 %X failed!!", OS2HwndFrame));
400 return FALSE;
401 }
402 }
403#endif
404
405 /* Set the window menu */
406 if ((dwStyle & (WS_CAPTION | WS_CHILD)) == WS_CAPTION )
407 {
408 if (cs->hMenu) SetMenu(cs->hMenu);
409 else
410 {
411 if (windowClass->getMenuNameA()) {
412 cs->hMenu = LoadMenuA(cs->hInstance, windowClass->getMenuNameA());
413 if (cs->hMenu) SetMenu(cs->hMenu );
414 }
415 }
416 }
417 else windowId = (UINT)cs->hMenu;
418
419 //Set icon from class
420 if(windowClass->getIcon())
421 SetIcon(windowClass->getIcon());
422
423 if(getParent()) {
424 SetWindowPos(getParent()->getWindowHandle(), rectClient.left, rectClient.top,
425 rectClient.right-rectClient.left,
426 rectClient.bottom-rectClient.top,
427 SWP_NOACTIVATE | SWP_NOZORDER);
428 }
429 else {
430 SetWindowPos(HWND_TOP, rectClient.left, rectClient.top,
431 rectClient.right-rectClient.left,
432 rectClient.bottom-rectClient.top,
433 SWP_NOACTIVATE);
434 }
435 //Get the client window rectangle
436 GetClientRect(Win32Hwnd, &rectClient);
437
438 /* Send the WM_CREATE message
439 * Perhaps we shouldn't allow width/height changes as well.
440 * See p327 in "Internals".
441 */
442 maxPos.x = rectWindow.left; maxPos.y = rectWindow.top;
443
444 fCreated = TRUE; //Allow WM_SIZE messages now
445 if(SendInternalMessage(WM_NCCREATE, 0, (LPARAM)cs) )
446 {
447 //doesn't work right, messes up client rectangle
448#if 0
449 SendNCCalcSize(FALSE, &rectWindow, NULL, NULL, 0, &rectClient );
450#endif
451 OffsetRect(&rectWindow, maxPos.x - rectWindow.left, maxPos.y - rectWindow.top);
452 dprintf(("Sending WM_CREATE"));
453 if( (SendInternalMessage(WM_CREATE, 0, (LPARAM)cs )) != -1 )
454 {
455 if(!(flags & WIN_NEED_SIZE)) {
456 SendMessageA(WM_SIZE, SIZE_RESTORED,
457 MAKELONG(rectClient.right-rectClient.left,
458 rectClient.bottom-rectClient.top));
459 SendMessageA(WM_MOVE, 0, MAKELONG( rectClient.left, rectClient.top ) );
460 }
461 if (cs->style & WS_VISIBLE) ShowWindow( sw );
462
463#if 0
464 /* Call WH_SHELL hook */
465
466 if (!(dwStyle & WS_CHILD) && !owner)
467 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
468#endif
469 SetLastError(0);
470 return TRUE;
471 }
472 }
473 fCreated = FALSE;
474 OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, 0);
475 OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, 0);
476 DestroyWindow();
477 return FALSE;
478}
479#if 0
480/***********************************************************************
481 * WINPOS_MinMaximize
482 *
483 * Fill in lpRect and return additional flags to be used with SetWindowPos().
484 * This function assumes that 'cmd' is different from the current window
485 * state.
486 */
487UINT Win32Window::MinMaximize(UINT cmd, LPRECT lpRect )
488{
489 UINT swpFlags = 0;
490 POINT pt, size;
491 LPINTERNALPOS lpPos;
492
493 size.x = rectWindow.left; size.y = rectWindow.top;
494 lpPos = WINPOS_InitInternalPos( wndPtr, size, &rectWindow );
495
496 if (lpPos && !HOOK_CallHooks16(WH_CBT, HCBT_MINMAX, hwndSelf, cmd))
497 {
498 if( dwStyle & WS_MINIMIZE )
499 {
500 if( !SendInternalMessageA(WM_QUERYOPEN, 0, 0L ) )
501 return (SWP_NOSIZE | SWP_NOMOVE);
502 swpFlags |= SWP_NOCOPYBITS;
503 }
504 switch( cmd )
505 {
506 case SW_MINIMIZE:
507 if( dwStyle & WS_MAXIMIZE)
508 {
509 flags |= WIN_RESTORE_MAX;
510 dwStyle &= ~WS_MAXIMIZE;
511 }
512 else
513 flags &= ~WIN_RESTORE_MAX;
514 dwStyle |= WS_MINIMIZE;
515
516#if 0
517 if( flags & WIN_NATIVE )
518 if( pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, TRUE ) )
519 swpFlags |= MINMAX_NOSWP;
520#endif
521
522 lpPos->ptIconPos = WINPOS_FindIconPos( wndPtr, lpPos->ptIconPos );
523
524 SetRect(lpRect, lpPos->ptIconPos.x, lpPos->ptIconPos.y,
525 GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON) );
526 swpFlags |= SWP_NOCOPYBITS;
527 break;
528
529 case SW_MAXIMIZE:
530 WINPOS_GetMinMaxInfo( wndPtr, &size, &pt, NULL, NULL );
531
532 if( dwStyle & WS_MINIMIZE )
533 {
534 if( flags & WIN_NATIVE )
535 if( pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, FALSE ) )
536 swpFlags |= MINMAX_NOSWP;
537
538 WINPOS_ShowIconTitle( wndPtr, FALSE );
539 dwStyle &= ~WS_MINIMIZE;
540 }
541 dwStyle |= WS_MAXIMIZE;
542
543 SetRect16( lpRect, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y,
544 size.x, size.y );
545 break;
546
547 case SW_RESTORE:
548 if( dwStyle & WS_MINIMIZE )
549 {
550 if( flags & WIN_NATIVE )
551 if( pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, FALSE ) )
552 swpFlags |= MINMAX_NOSWP;
553
554 dwStyle &= ~WS_MINIMIZE;
555 WINPOS_ShowIconTitle( wndPtr, FALSE );
556
557 if( flags & WIN_RESTORE_MAX)
558 {
559 /* Restore to maximized position */
560 CONV_POINT16TO32( &lpPos->ptMaxPos, &pt );
561 WINPOS_GetMinMaxInfo( wndPtr, &size, &pt, NULL, NULL);
562 CONV_POINT32TO16( &pt, &lpPos->ptMaxPos );
563 dwStyle |= WS_MAXIMIZE;
564 SetRect16( lpRect, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y, size.x, size.y );
565 break;
566 }
567 }
568 else
569 if( !(dwStyle & WS_MAXIMIZE) ) return (UINT16)(-1);
570 else dwStyle &= ~WS_MAXIMIZE;
571
572 /* Restore to normal position */
573
574 *lpRect = lpPos->rectNormal;
575 lpRect->right -= lpRect->left;
576 lpRect->bottom -= lpRect->top;
577
578 break;
579 }
580 } else swpFlags |= SWP_NOSIZE | SWP_NOMOVE;
581 return swpFlags;
582}
583#endif
584/*******************************************************************
585 * GetMinMaxInfo
586 *
587 * Get the minimized and maximized information for a window.
588 */
589void Win32Window::GetMinMaxInfo(POINT *maxSize, POINT *maxPos,
590 POINT *minTrack, POINT *maxTrack )
591{
592 MINMAXINFO MinMax;
593 INT xinc, yinc;
594
595 /* Compute default values */
596
597 MinMax.ptMaxSize.x = GetSystemMetrics(SM_CXSCREEN);
598 MinMax.ptMaxSize.y = GetSystemMetrics(SM_CYSCREEN);
599 MinMax.ptMinTrackSize.x = GetSystemMetrics(SM_CXMINTRACK);
600 MinMax.ptMinTrackSize.y = GetSystemMetrics(SM_CYMINTRACK);
601 MinMax.ptMaxTrackSize.x = GetSystemMetrics(SM_CXSCREEN);
602 MinMax.ptMaxTrackSize.y = GetSystemMetrics(SM_CYSCREEN);
603
604 if (flags & WIN_MANAGED) xinc = yinc = 0;
605 else if (HAS_DLGFRAME( dwStyle, dwExStyle ))
606 {
607 xinc = GetSystemMetrics(SM_CXDLGFRAME);
608 yinc = GetSystemMetrics(SM_CYDLGFRAME);
609 }
610 else
611 {
612 xinc = yinc = 0;
613 if (HAS_THICKFRAME(dwStyle))
614 {
615 xinc += GetSystemMetrics(SM_CXFRAME);
616 yinc += GetSystemMetrics(SM_CYFRAME);
617 }
618 if (dwStyle & WS_BORDER)
619 {
620 xinc += GetSystemMetrics(SM_CXBORDER);
621 yinc += GetSystemMetrics(SM_CYBORDER);
622 }
623 }
624 MinMax.ptMaxSize.x += 2 * xinc;
625 MinMax.ptMaxSize.y += 2 * yinc;
626
627#if 0
628 lpPos = (LPINTERNALPOS)GetPropA( hwndSelf, atomInternalPos );
629 if( lpPos && !EMPTYPOINT(lpPos->ptMaxPos) )
630 CONV_POINT16TO32( &lpPos->ptMaxPos, &MinMax.ptMaxPosition );
631 else
632 {
633#endif
634 MinMax.ptMaxPosition.x = -xinc;
635 MinMax.ptMaxPosition.y = -yinc;
636// }
637
638 SendInternalMessageA(WM_GETMINMAXINFO, 0, (LPARAM)&MinMax );
639
640 /* Some sanity checks */
641
642 dprintf(("GetMinMaxInfo: %ld %ld / %ld %ld / %ld %ld / %ld %ld\n",
643 MinMax.ptMaxSize.x, MinMax.ptMaxSize.y,
644 MinMax.ptMaxPosition.x, MinMax.ptMaxPosition.y,
645 MinMax.ptMaxTrackSize.x, MinMax.ptMaxTrackSize.y,
646 MinMax.ptMinTrackSize.x, MinMax.ptMinTrackSize.y));
647 MinMax.ptMaxTrackSize.x = MAX( MinMax.ptMaxTrackSize.x,
648 MinMax.ptMinTrackSize.x );
649 MinMax.ptMaxTrackSize.y = MAX( MinMax.ptMaxTrackSize.y,
650 MinMax.ptMinTrackSize.y );
651
652 if (maxSize) *maxSize = MinMax.ptMaxSize;
653 if (maxPos) *maxPos = MinMax.ptMaxPosition;
654 if (minTrack) *minTrack = MinMax.ptMinTrackSize;
655 if (maxTrack) *maxTrack = MinMax.ptMaxTrackSize;
656}
657/***********************************************************************
658 * WINPOS_SendNCCalcSize
659 *
660 * Send a WM_NCCALCSIZE message to a window.
661 * All parameters are read-only except newClientRect.
662 * oldWindowRect, oldClientRect and winpos must be non-NULL only
663 * when calcValidRect is TRUE.
664 */
665LONG Win32Window::SendNCCalcSize(BOOL calcValidRect, RECT *newWindowRect, RECT *oldWindowRect,
666 RECT *oldClientRect, WINDOWPOS *winpos,
667 RECT *newClientRect )
668{
669 NCCALCSIZE_PARAMS params;
670 WINDOWPOS winposCopy;
671 LONG result;
672
673 params.rgrc[0] = *newWindowRect;
674 if (calcValidRect)
675 {
676 winposCopy = *winpos;
677 params.rgrc[1] = *oldWindowRect;
678 params.rgrc[2] = *oldClientRect;
679 params.lppos = &winposCopy;
680 }
681 result = SendInternalMessageA(WM_NCCALCSIZE, calcValidRect,
682 (LPARAM)&params );
683 *newClientRect = params.rgrc[0];
684 return result;
685}
686//******************************************************************************
687//******************************************************************************
688ULONG Win32Window::MsgCreate(HWND hwndOS2, ULONG initParam)
689{
690 OS2Hwnd = hwndOS2;
691 return SendInternalMessageA(WM_CREATE, 0, initParam);
692}
693//******************************************************************************
694//******************************************************************************
695ULONG Win32Window::MsgQuit()
696{
697 return SendInternalMessageA(WM_QUIT, 0, 0);
698}
699//******************************************************************************
700//******************************************************************************
701ULONG Win32Window::MsgClose()
702{
703 if(SendInternalMessageA(WM_CLOSE, 0, 0) == 0) {
704 return 0; //app handles this message
705 }
706 delete this;
707 return 1;
708}
709//******************************************************************************
710//******************************************************************************
711ULONG Win32Window::MsgDestroy()
712{
713 ULONG rc;
714
715 rc = SendInternalMessageA(WM_DESTROY, 0, 0);
716 delete this;
717 return rc;
718}
719//******************************************************************************
720//******************************************************************************
721ULONG Win32Window::MsgEnable(BOOL fEnable)
722{
723 return SendInternalMessageA(WM_ENABLE, fEnable, 0);
724}
725//******************************************************************************
726//TODO: SW_PARENTCLOSING/OPENING flag (lParam)
727//******************************************************************************
728ULONG Win32Window::MsgShow(BOOL fShow)
729{
730 return SendInternalMessageA(WM_SHOWWINDOW, fShow, 0);
731}
732//******************************************************************************
733//******************************************************************************
734ULONG Win32Window::MsgPosChanging(LPARAM lp)
735{
736 dprintf(("MsgPosChanging"));
737#if 1
738 if(fCreated == FALSE) {
739 return 1;
740 }
741#endif
742 return SendInternalMessageA(WM_WINDOWPOSCHANGING, 0, lp);
743}
744//******************************************************************************
745//******************************************************************************
746ULONG Win32Window::MsgPosChanged(LPARAM lp)
747{
748 dprintf(("MsgPosChanged"));
749#if 1
750 if(fCreated == FALSE) {
751 return 1;
752 }
753#endif
754 return SendInternalMessageA(WM_WINDOWPOSCHANGED, 0, lp);
755}
756//******************************************************************************
757//******************************************************************************
758ULONG Win32Window::MsgMove(ULONG x, ULONG y)
759{
760 dprintf(("MsgMove to (%d,%d)", x, y));
761 if(fCreated == FALSE) {
762 return 1;
763 }
764
765 return SendInternalMessageA(WM_MOVE, 0, MAKELONG((USHORT)x, (USHORT)y));
766}
767//******************************************************************************
768//******************************************************************************
769ULONG Win32Window::MsgCommand(ULONG cmd, ULONG Id, HWND hwnd)
770{
771 switch(cmd) {
772 case CMD_MENU:
773 return SendInternalMessageA(WM_COMMAND, MAKELONG(Id, 0), 0);
774 case CMD_CONTROL:
775 return 0; //todo
776 case CMD_ACCELERATOR:
777 dprintf(("accelerator command"));
778 return 0; //todo
779 }
780 return 0;
781}
782//******************************************************************************
783//******************************************************************************
784ULONG Win32Window::MsgHitTest(ULONG x, ULONG y)
785{
786 lastHitTestVal = SendInternalMessageA(WM_NCHITTEST, 0, MAKELONG((USHORT)x, (USHORT)y));
787 return 1; //TODO: May need to change this
788}
789//******************************************************************************
790//TODO: Send WM_NCCALCSIZE message here and correct size if necessary
791//******************************************************************************
792ULONG Win32Window::MsgSize(ULONG width, ULONG height, BOOL fMinimize, BOOL fMaximize)
793{
794 WORD fwSizeType = 0;
795
796 if(fCreated == FALSE) {//Solitaire crashes if it receives a WM_SIZE during CreateWindowEx (normal or our fault?)
797 return 1;
798 }
799
800 if(fMinimize) {
801 fwSizeType = SIZE_MINIMIZED;
802 }
803 else
804 if(fMaximize) {
805 fwSizeType = SIZE_MAXIMIZED;
806 }
807 else fwSizeType = SIZE_RESTORED;
808
809 return SendInternalMessageA(WM_SIZE, fwSizeType, MAKELONG((USHORT)width, (USHORT)height));
810}
811//******************************************************************************
812//******************************************************************************
813ULONG Win32Window::MsgActivate(BOOL fActivate, HWND hwnd)
814{
815 if(SendInternalMessageA(WM_NCACTIVATE, fActivate, 0) == FALSE)
816 {
817 if(!fActivate) {
818 return 1;
819 }
820 }
821 return SendInternalMessageA(WM_ACTIVATE, (fActivate) ? WA_ACTIVE : WA_INACTIVE, hwnd);
822}
823//******************************************************************************
824//******************************************************************************
825ULONG Win32Window::MsgSysCommand(ULONG win32sc, ULONG x, ULONG y)
826{
827 return SendInternalMessageA(WM_SYSCOMMAND, win32sc, MAKELONG((USHORT)x, (USHORT)y));
828}
829//******************************************************************************
830//TODO: virtual key & (possibly) scancode translation, extended keyboard bit & Unicode
831//******************************************************************************
832ULONG Win32Window::MsgChar(ULONG cmd, ULONG repeatcnt, ULONG scancode, ULONG vkey, ULONG keyflags)
833{
834 ULONG lParam = 0;
835
836 lParam = repeatcnt;
837 lParam |= (scancode << 16);
838 if(keyflags & KEY_ALTDOWN)
839 lParam |= (1<<29);
840 if(keyflags & KEY_PREVDOWN)
841 lParam |= (1<<30);
842 if(keyflags & KEY_UP)
843 lParam |= (1<<31);
844 if(keyflags & KEY_DEADKEY) {
845 dprintf(("WM_DEADCHAR: %x %x %08x", OS2Hwnd, cmd, lParam));
846 return SendInternalMessageA(WM_DEADCHAR, cmd, lParam);
847 }
848 else {
849 dprintf(("WM_CHAR: %x %x %08x", OS2Hwnd, cmd, lParam));
850 return SendInternalMessageA(WM_CHAR, cmd, lParam);
851 }
852}
853//******************************************************************************
854//******************************************************************************
855ULONG Win32Window::MsgSetFocus(HWND hwnd)
856{
857 if(hwnd == 0) {
858 //other app lost focus
859 SendInternalMessageA(WM_ACTIVATEAPP, TRUE, 0); //TODO: Need thread id from hwnd app
860 }
861 return SendInternalMessageA(WM_SETFOCUS, hwnd, 0);
862}
863//******************************************************************************
864//******************************************************************************
865ULONG Win32Window::MsgKillFocus(HWND hwnd)
866{
867 if(hwnd == 0) {
868 //other app lost focus
869 SendInternalMessageA(WM_ACTIVATEAPP, FALSE, 0); //TODO: Need thread id from hwnd app
870 }
871 return SendInternalMessageA(WM_KILLFOCUS, hwnd, 0);
872}
873//******************************************************************************
874//******************************************************************************
875ULONG Win32Window::MsgButton(ULONG msg, ULONG ncx, ULONG ncy, ULONG clx, ULONG cly)
876{
877 ULONG win32msg;
878 ULONG win32ncmsg;
879
880 dprintf(("MsgButton to (%d,%d)", ncx, ncy));
881 switch(msg) {
882 case BUTTON_LEFTDOWN:
883 win32msg = WM_LBUTTONDOWN;
884 win32ncmsg = WM_NCLBUTTONDOWN;
885 break;
886 case BUTTON_LEFTUP:
887 win32msg = WM_LBUTTONUP;
888 win32ncmsg = WM_NCLBUTTONUP;
889 break;
890 case BUTTON_LEFTDBLCLICK:
891 win32msg = WM_LBUTTONDBLCLK;
892 win32ncmsg = WM_NCLBUTTONDBLCLK;
893 break;
894 case BUTTON_RIGHTUP:
895 win32msg = WM_RBUTTONUP;
896 win32ncmsg = WM_NCRBUTTONUP;
897 break;
898 case BUTTON_RIGHTDOWN:
899 win32msg = WM_RBUTTONDOWN;
900 win32ncmsg = WM_NCRBUTTONDOWN;
901 break;
902 case BUTTON_RIGHTDBLCLICK:
903 win32msg = WM_RBUTTONDBLCLK;
904 win32ncmsg = WM_NCRBUTTONDBLCLK;
905 break;
906 case BUTTON_MIDDLEUP:
907 win32msg = WM_MBUTTONUP;
908 win32ncmsg = WM_NCMBUTTONUP;
909 break;
910 case BUTTON_MIDDLEDOWN:
911 win32msg = WM_MBUTTONDOWN;
912 win32ncmsg = WM_NCMBUTTONDOWN;
913 break;
914 case BUTTON_MIDDLEDBLCLICK:
915 win32msg = WM_MBUTTONDBLCLK;
916 win32ncmsg = WM_NCMBUTTONDBLCLK;
917 break;
918 default:
919 dprintf(("Win32Window::Button: invalid msg!!!!"));
920 return 1;
921 }
922 if(win32msg == WM_MBUTTONDBLCLK || win32msg == WM_RBUTTONDBLCLK || win32msg == WM_LBUTTONDBLCLK) {
923 if(!(windowClass->getClassLongA(GCL_STYLE) & CS_DBLCLKS)) {
924 return 1;
925 }
926 }
927 SendInternalMessageA(win32ncmsg, lastHitTestVal, MAKELONG(ncx, ncy)); //TODO:
928 return SendInternalMessageA(win32msg, 0, MAKELONG(clx, cly));
929}
930//******************************************************************************
931//******************************************************************************
932ULONG Win32Window::MsgMouseMove(ULONG keystate, ULONG x, ULONG y)
933{
934 ULONG winstate = 0;
935
936 if(keystate & WMMOVE_LBUTTON)
937 winstate |= MK_LBUTTON;
938 if(keystate & WMMOVE_RBUTTON)
939 winstate |= MK_RBUTTON;
940 if(keystate & WMMOVE_MBUTTON)
941 winstate |= MK_MBUTTON;
942 if(keystate & WMMOVE_SHIFT)
943 winstate |= MK_SHIFT;
944 if(keystate & WMMOVE_CTRL)
945 winstate |= MK_CONTROL;
946
947 return SendInternalMessageA(WM_MOUSEMOVE, keystate, MAKELONG(x, y));
948}
949//******************************************************************************
950//******************************************************************************
951ULONG Win32Window::MsgPaint(ULONG tmp1, ULONG tmp2)
952{
953 return SendInternalMessageA(WM_PAINT, 0, 0);
954}
955//******************************************************************************
956//TODO: Is the clipper region of the window DC equal to the invalidated rectangle?
957// (or are we simply erasing too much here)
958//******************************************************************************
959ULONG Win32Window::MsgEraseBackGround(HDC hdc)
960{
961 if(isIcon) {
962 return SendInternalMessageA(WM_ICONERASEBKGND, hdc, 0);
963 }
964 else return SendInternalMessageA(WM_ERASEBKGND, hdc, 0);
965}
966//******************************************************************************
967//******************************************************************************
968ULONG Win32Window::MsgSetText(LPSTR lpsz, LONG cch)
969{
970 if(isUnicode) {
971 return SendInternalMessageW(WM_SETTEXT, 0, (LPARAM)lpsz);
972 }
973 else return SendInternalMessageA(WM_SETTEXT, 0, (LPARAM)lpsz);
974}
975//******************************************************************************
976//TODO: in- or excluding terminating 0?
977//******************************************************************************
978ULONG Win32Window::MsgGetTextLength()
979{
980 return SendInternalMessageA(WM_GETTEXTLENGTH, 0, 0);
981}
982//******************************************************************************
983//******************************************************************************
984char *Win32Window::MsgGetText()
985{
986 if(isUnicode) {
987 SendInternalMessageW(WM_GETTEXT, MAX_WINDOW_NAMELENGTH, (LPARAM)windowNameW);
988 }
989 else {
990 SendInternalMessageA(WM_GETTEXT, MAX_WINDOW_NAMELENGTH, (LPARAM)windowNameA);
991 }
992 return windowNameA;
993}
994//******************************************************************************
995//******************************************************************************
996LRESULT Win32Window::DefWindowProcA(UINT Msg, WPARAM wParam, LPARAM lParam)
997{
998 switch(Msg)
999 {
1000 case WM_GETTEXTLENGTH:
1001 return wndNameLength;
1002
1003 case WM_GETTEXT: //TODO: SS_ICON controls
1004 strncpy((LPSTR)lParam, windowNameA, wParam);
1005 return min(wndNameLength, wParam);
1006
1007 case WM_SETTEXT:
1008 return 0;
1009
1010 case WM_SETREDRAW:
1011 if(wParam)
1012 SetWindowLongA (GWL_STYLE, GetWindowLongA (GWL_STYLE) | WS_VISIBLE);
1013 else SetWindowLongA (GWL_STYLE, GetWindowLongA (GWL_STYLE) & ~WS_VISIBLE);
1014
1015 return 0; //TODO
1016
1017 case WM_NCCREATE:
1018 return(TRUE);
1019
1020 case WM_CTLCOLORMSGBOX:
1021 case WM_CTLCOLOREDIT:
1022 case WM_CTLCOLORLISTBOX:
1023 case WM_CTLCOLORBTN:
1024 case WM_CTLCOLORDLG:
1025 case WM_CTLCOLORSTATIC:
1026 case WM_CTLCOLORSCROLLBAR:
1027 SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW));
1028 SetTextColor((HDC)wParam, GetSysColor(COLOR_WINDOWTEXT));
1029 return GetSysColorBrush(COLOR_BTNFACE);
1030
1031 case WM_PARENTNOTIFY:
1032 return 0;
1033
1034 case WM_MOUSEACTIVATE:
1035 {
1036 DWORD dwStyle = GetWindowLongA(GWL_STYLE);
1037 DWORD dwExStyle = GetWindowLongA(GWL_EXSTYLE);
1038 dprintf(("DefWndProc: WM_MOUSEACTIVATE for %x Msg %s", Win32Hwnd, GetMsgText(HIWORD(lParam))));
1039 if(dwStyle & WS_CHILD && !(dwExStyle & WS_EX_NOPARENTNOTIFY) )
1040 {
1041 if(getParent()) {
1042 LRESULT rc = getParent()->SendMessageA(WM_MOUSEACTIVATE, wParam, lParam );
1043 if(rc) return rc;
1044 }
1045 }
1046 return (LOWORD(lParam) == HTCAPTION) ? MA_NOACTIVATE : MA_ACTIVATE;
1047 }
1048 case WM_SETCURSOR:
1049 {
1050 DWORD dwStyle = GetWindowLongA(GWL_STYLE);
1051 DWORD dwExStyle = GetWindowLongA(GWL_EXSTYLE);
1052 dprintf(("DefWndProc: WM_SETCURSOR for %x Msg %s", Win32Hwnd, GetMsgText(HIWORD(lParam))));
1053 if(dwStyle & WS_CHILD && !(dwExStyle & WS_EX_NOPARENTNOTIFY) )
1054 {
1055 if(getParent()) {
1056 LRESULT rc = getParent()->SendMessageA(WM_SETCURSOR, wParam, lParam);
1057 if(rc) return rc;
1058 }
1059 }
1060 return 1;
1061 }
1062 case WM_MOUSEMOVE:
1063 return 0;
1064
1065 case WM_WINDOWPOSCHANGED:
1066 {
1067
1068/* undocumented SWP flags - from SDK 3.1 */
1069#define SWP_NOCLIENTSIZE 0x0800
1070#define SWP_NOCLIENTMOVE 0x1000
1071
1072 PWINDOWPOS wpos = (PWINDOWPOS)lParam;
1073 WPARAM wp = SIZE_RESTORED;
1074
1075 if (!(wpos->flags & SWP_NOCLIENTMOVE))
1076 SendMessageA(WM_MOVE, 0, MAKELONG(rectClient.left, rectClient.top));
1077
1078 if (!(wpos->flags & SWP_NOCLIENTSIZE))
1079 {
1080 if (dwStyle & WS_MAXIMIZE) wp = SIZE_MAXIMIZED;
1081 else if (dwStyle & WS_MINIMIZE) wp = SIZE_MINIMIZED;
1082
1083 SendMessageA(WM_SIZE, wp, MAKELONG(rectClient.right - rectClient.left,
1084 rectClient.bottom - rectClient.top));
1085 }
1086 return 0;
1087 }
1088 case WM_ERASEBKGND:
1089 case WM_ICONERASEBKGND:
1090 {
1091 RECT rect;
1092
1093 if (!windowClass->getBackgroundBrush()) return 0;
1094
1095 /* Since WM_ERASEBKGND may receive either a window dc or a */
1096 /* client dc, the area to be erased has to be retrieved from */
1097 /* the device context. */
1098 GetClipBox( (HDC)wParam, &rect );
1099
1100 FillRect( (HDC)wParam, &rect, windowClass->getBackgroundBrush());
1101
1102 return 1;
1103 }
1104
1105 case WM_NCLBUTTONDOWN:
1106 case WM_NCLBUTTONUP:
1107 case WM_NCLBUTTONDBLCLK:
1108 case WM_NCRBUTTONUP:
1109 case WM_NCRBUTTONDOWN:
1110 case WM_NCRBUTTONDBLCLK:
1111 case WM_NCMBUTTONDOWN:
1112 case WM_NCMBUTTONUP:
1113 case WM_NCMBUTTONDBLCLK:
1114 return 0; //TODO: Send WM_SYSCOMMAND if required
1115
1116 case WM_NCHITTEST: //TODO:
1117 return 0;
1118
1119 default:
1120 return 1;
1121 }
1122}
1123//******************************************************************************
1124//******************************************************************************
1125LRESULT Win32Window::DefWindowProcW(UINT Msg, WPARAM wParam, LPARAM lParam)
1126{
1127 switch(Msg)
1128 {
1129 case WM_GETTEXTLENGTH:
1130 return wndNameLength;
1131
1132 case WM_GETTEXT: //TODO: SS_ICON controls
1133 lstrcpynW((LPWSTR)lParam, windowNameW, wParam);
1134 return min(wndNameLength, wParam);
1135
1136 default:
1137 return DefWindowProcA(Msg, wParam, lParam);
1138 }
1139}
1140//******************************************************************************
1141//******************************************************************************
1142LRESULT Win32Window::SendMessageA(ULONG Msg, WPARAM wParam, LPARAM lParam)
1143{
1144 if(PostSpyMessage(getWindowHandle(), Msg, wParam, lParam) == FALSE)
1145 dprintf(("SendMessageA %s for %x %x %x", GetMsgText(Msg), getWindowHandle(), wParam, lParam));
1146
1147 if(HkCBT::OS2HkCBTProc(getWindowHandle(), Msg, wParam, lParam) == TRUE) {//hook swallowed msg
1148 return(0);
1149 }
1150 switch(Msg)
1151 {
1152 case WM_CREATE:
1153 {
1154 if(win32wndproc(getWindowHandle(), WM_NCCREATE, 0, lParam) == 0) {
1155 dprintf(("WM_NCCREATE returned FALSE\n"));
1156 return(-1); //don't create window
1157 }
1158 if(win32wndproc(getWindowHandle(), WM_CREATE, 0, lParam) == -1) {
1159 dprintf(("WM_CREATE returned -1\n"));
1160 return(-1); //don't create window
1161 }
1162 NotifyParent(Msg, wParam, lParam);
1163
1164 return(0);
1165 }
1166 case WM_SETTEXT: //TODO: Nothing happens if passed to DefWindowProc
1167 return win32wndproc(getWindowHandle(), WM_SETTEXT, wParam, lParam);
1168
1169 case WM_LBUTTONDOWN:
1170 case WM_MBUTTONDOWN:
1171 case WM_RBUTTONDOWN:
1172 NotifyParent(Msg, wParam, lParam);
1173 return win32wndproc(getWindowHandle(), Msg, wParam, lParam);
1174
1175 case WM_DESTROY:
1176 win32wndproc(getWindowHandle(), WM_NCDESTROY, 0, 0);
1177 NotifyParent(Msg, wParam, lParam);
1178 return win32wndproc(getWindowHandle(), WM_DESTROY, 0, 0);
1179 default:
1180 return win32wndproc(getWindowHandle(), Msg, wParam, lParam);
1181 }
1182}
1183//******************************************************************************
1184//******************************************************************************
1185LRESULT Win32Window::SendMessageW(ULONG Msg, WPARAM wParam, LPARAM lParam)
1186{
1187 if(PostSpyMessage(getWindowHandle(), Msg, wParam, lParam) == FALSE)
1188 dprintf(("SendMessageA %s for %x %x %x", GetMsgText(Msg), getWindowHandle(), wParam, lParam));
1189
1190 if(HkCBT::OS2HkCBTProc(getWindowHandle(), Msg, wParam, lParam) == TRUE) {//hook swallowed msg
1191 return(0);
1192 }
1193 switch(Msg)
1194 {
1195 case WM_CREATE:
1196 {
1197 if(win32wndproc(getWindowHandle(), WM_NCCREATE, 0, lParam) == 0) {
1198 dprintf(("WM_NCCREATE returned FALSE\n"));
1199 return(0); //don't create window
1200 }
1201 if(win32wndproc(getWindowHandle(), WM_CREATE, 0, lParam) == 0) {
1202 dprintf(("WM_CREATE returned FALSE\n"));
1203 return(0); //don't create window
1204 }
1205 NotifyParent(Msg, wParam, lParam);
1206
1207 return(1);
1208 }
1209 case WM_SETTEXT: //TODO: Nothing happens if passed to DefWindowProc
1210 return win32wndproc(getWindowHandle(), WM_SETTEXT, wParam, lParam);
1211
1212 case WM_LBUTTONDOWN:
1213 case WM_MBUTTONDOWN:
1214 case WM_RBUTTONDOWN:
1215 NotifyParent(Msg, wParam, lParam);
1216 return win32wndproc(getWindowHandle(), Msg, wParam, lParam);
1217
1218 case WM_DESTROY:
1219 win32wndproc(getWindowHandle(), WM_NCDESTROY, 0, 0);
1220 NotifyParent(Msg, wParam, lParam);
1221 return win32wndproc(getWindowHandle(), WM_DESTROY, 0, 0);
1222
1223 default:
1224 return win32wndproc(getWindowHandle(), Msg, wParam, lParam);
1225 }
1226}
1227//******************************************************************************
1228//Called as a result of an OS/2 message
1229//******************************************************************************
1230LRESULT Win32Window::SendInternalMessageA(ULONG Msg, WPARAM wParam, LPARAM lParam)
1231{
1232 if(PostSpyMessage(getWindowHandle(), Msg, wParam, lParam) == FALSE)
1233 dprintf(("SendInternalMessageA %s for %x %x %x", GetMsgText(Msg), getWindowHandle(), wParam, lParam));
1234
1235 if(HkCBT::OS2HkCBTProc(getWindowHandle(), Msg, wParam, lParam) == TRUE) {//hook swallowed msg
1236 return(0);
1237 }
1238 switch(Msg)
1239 {
1240 case WM_CREATE:
1241 {
1242 if(win32wndproc(getWindowHandle(), WM_NCCREATE, 0, lParam) == 0) {
1243 dprintf(("WM_NCCREATE returned FALSE\n"));
1244 return(0); //don't create window
1245 }
1246 if(win32wndproc(getWindowHandle(), WM_CREATE, 0, lParam) == 0) {
1247 dprintf(("WM_CREATE returned FALSE\n"));
1248 return(0); //don't create window
1249 }
1250 NotifyParent(Msg, wParam, lParam);
1251
1252 return(1);
1253 }
1254 case WM_LBUTTONDOWN:
1255 case WM_MBUTTONDOWN:
1256 case WM_RBUTTONDOWN:
1257 NotifyParent(Msg, wParam, lParam);
1258 return win32wndproc(getWindowHandle(), Msg, wParam, lParam);
1259
1260 case WM_DESTROY:
1261 win32wndproc(getWindowHandle(), WM_NCDESTROY, 0, 0);
1262 NotifyParent(Msg, wParam, lParam);
1263 return win32wndproc(getWindowHandle(), WM_DESTROY, 0, 0);
1264 default:
1265 return win32wndproc(getWindowHandle(), Msg, wParam, lParam);
1266 }
1267}
1268//******************************************************************************
1269//Called as a result of an OS/2 message
1270//todo, unicode msgs (WM_SETTEXT etc)
1271//******************************************************************************
1272LRESULT Win32Window::SendInternalMessageW(ULONG Msg, WPARAM wParam, LPARAM lParam)
1273{
1274 if(PostSpyMessage(getWindowHandle(), Msg, wParam, lParam) == FALSE)
1275 dprintf(("SendInternalMessageW %s for %x %x %x", GetMsgText(Msg), getWindowHandle(), wParam, lParam));
1276
1277 if(HkCBT::OS2HkCBTProc(getWindowHandle(), Msg, wParam, lParam) == TRUE) {//hook swallowed msg
1278 return(0);
1279 }
1280 switch(Msg)
1281 {
1282 case WM_CREATE:
1283 {
1284 if(win32wndproc(getWindowHandle(), WM_NCCREATE, 0, lParam) == 0) {
1285 dprintf(("WM_NCCREATE returned FALSE\n"));
1286 return(0); //don't create window
1287 }
1288 if(win32wndproc(getWindowHandle(), WM_CREATE, 0, lParam) == 0) {
1289 dprintf(("WM_CREATE returned FALSE\n"));
1290 return(0); //don't create window
1291 }
1292 NotifyParent(Msg, wParam, lParam);
1293
1294 return(1);
1295 }
1296 case WM_LBUTTONDOWN:
1297 case WM_MBUTTONDOWN:
1298 case WM_RBUTTONDOWN:
1299 NotifyParent(Msg, wParam, lParam);
1300 return win32wndproc(getWindowHandle(), Msg, wParam, lParam);
1301
1302 case WM_DESTROY:
1303 win32wndproc(getWindowHandle(), WM_NCDESTROY, 0, 0);
1304 NotifyParent(Msg, wParam, lParam);
1305 return win32wndproc(getWindowHandle(), WM_DESTROY, 0, 0);
1306 default:
1307 return win32wndproc(getWindowHandle(), Msg, wParam, lParam);
1308 }
1309}
1310//******************************************************************************
1311//******************************************************************************
1312BOOL Win32Window::PostMessageA(ULONG msg, WPARAM wParam, LPARAM lParam)
1313{
1314 POSTMSG_PACKET *postmsg;
1315
1316 postmsg = (POSTMSG_PACKET *)malloc(sizeof(POSTMSG_PACKET));
1317 if(postmsg == NULL) {
1318 dprintf(("Win32Window::PostMessageA: malloc returned NULL!!"));
1319 return 0;
1320 }
1321 postmsg->Msg = msg;
1322 postmsg->wParam = wParam;
1323 postmsg->lParam = lParam;
1324 return OSLibPostMessage(OS2Hwnd, WM_WIN32_POSTMESSAGEA, (ULONG)postmsg, 0);
1325}
1326//******************************************************************************
1327//******************************************************************************
1328BOOL Win32Window::PostMessageW(ULONG msg, WPARAM wParam, LPARAM lParam)
1329{
1330 POSTMSG_PACKET *postmsg;
1331
1332 postmsg = (POSTMSG_PACKET *)malloc(sizeof(POSTMSG_PACKET));
1333 if(postmsg == NULL) {
1334 dprintf(("Win32Window::PostMessageW: malloc returned NULL!!"));
1335 return 0;
1336 }
1337 postmsg->Msg = msg;
1338 postmsg->wParam = wParam;
1339 postmsg->lParam = lParam;
1340 return OSLibPostMessage(OS2Hwnd, WM_WIN32_POSTMESSAGEW, (ULONG)postmsg, 0);
1341}
1342//******************************************************************************
1343//TODO: do we need to inform the parent of the parent (etc) of the child window?
1344//******************************************************************************
1345void Win32Window::NotifyParent(UINT Msg, WPARAM wParam, LPARAM lParam)
1346{
1347 Win32Window *window = this;
1348 Win32Window *parentwindow;
1349
1350 while(window)
1351 {
1352 if(window->getStyle() & WS_CHILD && !(window->getExStyle() & WS_EX_NOPARENTNOTIFY) )
1353 {
1354 /* Notify the parent window only */
1355 parentwindow = window->getParent();
1356 if(parentwindow) {
1357 if(Msg == WM_CREATE || Msg == WM_DESTROY) {
1358 parentwindow->SendInternalMessageA(WM_PARENTNOTIFY, MAKEWPARAM(Msg, window->getWindowId()), (LPARAM)window->getWindowHandle());
1359 }
1360 else parentwindow->SendInternalMessageA(WM_PARENTNOTIFY, MAKEWPARAM(Msg, window->getWindowId()), lParam );
1361 }
1362 }
1363 else break;
1364
1365 window = parentwindow;
1366 }
1367}
1368//******************************************************************************
1369//******************************************************************************
1370BOOL Win32Window::SetMenu(HMENU hMenu)
1371{
1372 PVOID menutemplate;
1373 Win32Resource *winres = (Win32Resource *)hMenu;
1374
1375 dprintf(("SetMenu %x", hMenu));
1376 if(HIWORD(winres) == 0) {
1377 dprintf(("Win32Window:: Win32Resource *winres == 0"));
1378 SetLastError(ERROR_INVALID_PARAMETER);
1379 return FALSE;
1380 }
1381 menutemplate = winres->lockOS2Resource();
1382 if(menutemplate == NULL)
1383 {
1384 dprintf(("Win32Window::SetMenu menutemplate == 0"));
1385 return FALSE;
1386 }
1387 OS2HwndMenu = OSLibWinCreateMenu(OS2HwndFrame, menutemplate);
1388 if(OS2HwndMenu == 0) {
1389 dprintf(("Win32Window::SetMenu OS2HwndMenu == 0"));
1390 return FALSE;
1391 }
1392 menuResource = winres;
1393 return TRUE;
1394}
1395//******************************************************************************
1396//******************************************************************************
1397BOOL Win32Window::SetAccelTable(HACCEL hAccel)
1398{
1399 Win32Resource *winres = (Win32Resource *)hAccel;
1400 HANDLE accelhandle;
1401
1402 if(HIWORD(hAccel) == 0) {
1403 dprintf(("SetAccelTable: hAccel %x invalid", hAccel));
1404 SetLastError(ERROR_INVALID_PARAMETER);
1405 return FALSE;
1406 }
1407 acceltableResource = winres;
1408 accelhandle = OSLibWinSetAccelTable(OS2HwndFrame, winres->getOS2Handle(), winres->lockOS2Resource());
1409 winres->setOS2Handle(accelhandle);
1410 return(accelhandle != 0);
1411}
1412//******************************************************************************
1413//******************************************************************************
1414BOOL Win32Window::SetIcon(HICON hIcon)
1415{
1416 dprintf(("Win32Window::SetIcon %x", hIcon));
1417 return OSLibWinSetIcon(OS2HwndFrame, hIcon);
1418}
1419//******************************************************************************
1420//******************************************************************************
1421BOOL Win32Window::ShowWindow(ULONG nCmdShow)
1422{
1423 ULONG showstate = 0;
1424
1425 dprintf(("ShowWindow %x", nCmdShow));
1426 if(fFirstShow) {
1427 if(isFrameWindow() && IS_OVERLAPPED(getStyle())) {
1428 SendMessageA(WM_SIZE, SIZE_RESTORED,
1429 MAKELONG(rectClient.right-rectClient.left,
1430 rectClient.bottom-rectClient.top));
1431 SendMessageA(WM_MOVE, 0, MAKELONG( rectClient.left, rectClient.top ) );
1432
1433 }
1434 fFirstShow = FALSE;
1435 }
1436 switch(nCmdShow)
1437 {
1438 case SW_SHOW:
1439 case SW_SHOWDEFAULT: //todo
1440 showstate = SWPOS_SHOW | SWPOS_ACTIVATE;
1441 break;
1442 case SW_HIDE:
1443 showstate = SWPOS_HIDE;
1444 break;
1445 case SW_RESTORE:
1446 showstate = SWPOS_RESTORE | SWPOS_SHOW | SWPOS_ACTIVATE;
1447 break;
1448 case SW_MINIMIZE:
1449 showstate = SWPOS_MINIMIZE;
1450 break;
1451 case SW_SHOWMAXIMIZED:
1452 showstate = SWPOS_MAXIMIZE | SWPOS_SHOW | SWPOS_ACTIVATE;
1453 break;
1454 case SW_SHOWMINIMIZED:
1455 showstate = SWPOS_MINIMIZE | SWPOS_SHOW | SWPOS_ACTIVATE;
1456 break;
1457 case SW_SHOWMINNOACTIVE:
1458 showstate = SWPOS_MINIMIZE | SWPOS_SHOW;
1459 break;
1460 case SW_SHOWNA:
1461 showstate = SWPOS_SHOW;
1462 break;
1463 case SW_SHOWNOACTIVATE:
1464 showstate = SWPOS_SHOW;
1465 break;
1466 case SW_SHOWNORMAL:
1467 showstate = SWPOS_RESTORE | SWPOS_ACTIVATE | SWPOS_SHOW;
1468 break;
1469 }
1470 return OSLibWinShowWindow(OS2HwndFrame, showstate);
1471}
1472//******************************************************************************
1473//******************************************************************************
1474BOOL Win32Window::SetWindowPos(HWND hwndInsertAfter, int x, int y, int cx, int cy, UINT fuFlags)
1475{
1476 BOOL rc = FALSE;
1477 Win32Window *window;
1478 HWND hParent = 0;
1479
1480 dprintf (("SetWindowPos %x %x (%d,%d)(%d,%d) %x", Win32Hwnd, hwndInsertAfter, x, y, cx, cy, fuFlags));
1481
1482 /* Validate the flags passed in ... */
1483 if ( fuFlags &
1484 ~(SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER |
1485 SWP_NOREDRAW | SWP_NOACTIVATE | SWP_FRAMECHANGED |
1486 SWP_SHOWWINDOW | SWP_HIDEWINDOW | SWP_NOCOPYBITS |
1487 SWP_NOOWNERZORDER) )
1488 {
1489 return FALSE;
1490 }
1491
1492 WINDOWPOS wpos;
1493 SWP swp, swpOld;
1494
1495 //****************************
1496 // Set up with Windows values.
1497 //****************************
1498 wpos.flags = fuFlags;
1499 wpos.cy = cy;
1500 wpos.cx = cx;
1501 wpos.x = x;
1502 wpos.y = y;
1503 wpos.hwndInsertAfter = hwndInsertAfter;
1504 wpos.hwnd = getWindowHandle();
1505
1506 //**********************************************
1507 // Convert from Windows to PM coords and flags.
1508 //**********************************************
1509 if(~fuFlags & (SWP_NOMOVE | SWP_NOSIZE)) {
1510 if (isChild())
1511 {
1512 hParent = getParent()->getOS2WindowHandle();
1513 OSLibWinQueryWindowPos(OS2Hwnd, &swpOld);
1514 } else
1515 OSLibWinQueryWindowPos(OS2HwndFrame, &swpOld);
1516 }
1517 OSLibMapWINDOWPOStoSWP(&wpos, &swp, &swpOld, hParent, OS2HwndFrame);
1518
1519 /* MapSWP can clear the SWP_MOVE and SWP_SIZE flags if the window is not
1520 * being moved or sized. If these were the only operations to be done
1521 * and they have been cleared, return now.
1522 */
1523 if (swp.fl == 0)
1524 return TRUE;
1525
1526 //*********************************************************************
1527 //On Windows, a WM_GETMINMAXINFO is made to the app from within this API.
1528 //We'll send a WM_QUERYTRACKINFO which is translated into a WM_GETMINMAXINFO
1529 //and passed on to the app. Compare the values returned with the SWP cx and
1530 //cy values. They cannot be bigger than the max nor smaller than the min.
1531 //*********************************************************************
1532
1533 if ((swp.fl & SWPOS_ZORDER) && (swp.hwndInsertBehind > HWNDOS_BOTTOM))
1534 {
1535 Win32Window *wndBehind = Win32Window::GetWindowFromHandle(swp.hwndInsertBehind);
1536 swp.hwndInsertBehind = wndBehind->getOS2WindowHandle();
1537 }
1538 if (isFrameWindow())
1539 {
1540 POINT maxSize, maxPos, minTrack, maxTrack;
1541
1542 GetMinMaxInfo(&maxSize, &maxPos, &minTrack, &maxTrack);
1543
1544 if (swp.cx > maxTrack.x) swp.cx = maxTrack.x;
1545 if (swp.cy > maxTrack.y) swp.cy = maxTrack.y;
1546 if (swp.cx < minTrack.x) swp.cx = minTrack.x;
1547 if (swp.cy < minTrack.y) swp.cy = minTrack.y;
1548 swp.hwnd = OS2HwndFrame;
1549 } else
1550 swp.hwnd = OS2Hwnd;
1551 dprintf (("WinSetWindowPos %x %x (%d,%d)(%d,%d) %x", swp.hwnd, swp.hwndInsertBehind, swp.x, swp.y, swp.cx, swp.cy, swp.fl));
1552
1553 //*****************************************************************************
1554 // Squibble the window. (WinSetMultWindowPos is faster than WinSetWindowPos.)
1555 //*****************************************************************************
1556 rc = OSLibWinSetMultWindowPos(&swp, 1);
1557
1558 if (rc == FALSE)
1559 {
1560// SET_ERROR_LAST();
1561 }
1562 else
1563 {
1564 /* To implement support for SWP_FRAMECHANGED_W correctly, we would need
1565 ** to send a WM_NCCALCSIZE message. This means DAX would have to support
1566 ** the WM_NCCALCSIZE message. I don't think DAX can support this
1567 ** message because it is tightly bound with the architecture of
1568 ** overlapped windows (the "just one window" architecture). However,
1569 ** we *can* support the SWP_FRAMECHANGED flag by sending the window
1570 ** a WM_UPDATEFRAME, which will provide the behavior of WM_NCCALCSIZE.
1571 */
1572// if (fuFlags & SWP_FRAMECHANGED_W)
1573// WinSendMsg(hWindow, WM_UPDATEFRAME, (MPARAM)-1, 0);
1574 }
1575
1576 return (rc);
1577}
1578//******************************************************************************
1579//Also destroys all the child windows (destroy parent, destroy children)
1580//******************************************************************************
1581BOOL Win32Window::DestroyWindow()
1582{
1583 return OSLibWinDestroyWindow(OS2HwndFrame);
1584}
1585//******************************************************************************
1586//******************************************************************************
1587HWND Win32Window::GetParent()
1588{
1589 if(getParent()) {
1590 return getParent()->getWindowHandle();
1591 }
1592 else return 0;
1593}
1594//******************************************************************************
1595//******************************************************************************
1596HWND Win32Window::SetParent(HWND hwndNewParent)
1597{
1598 HWND oldhwnd;
1599 Win32Window *newparent;
1600
1601 if(getParent()) {
1602 oldhwnd = getParent()->getWindowHandle();
1603 }
1604 else oldhwnd = 0;
1605
1606 if(hwndNewParent == 0) {//desktop window = parent
1607 setParent(NULL);
1608 OSLibWinSetParent(getOS2WindowHandle(), OSLIB_HWND_DESKTOP);
1609 return oldhwnd;
1610 }
1611 newparent = GetWindowFromHandle(hwndNewParent);
1612 if(newparent)
1613 {
1614 setParent(newparent);
1615 OSLibWinSetParent(getOS2WindowHandle(), getParent()->getOS2WindowHandle());
1616 return oldhwnd;
1617 }
1618 SetLastError(ERROR_INVALID_PARAMETER);
1619 return 0;
1620}
1621//******************************************************************************
1622//******************************************************************************
1623BOOL Win32Window::IsChild(HWND hwndParent)
1624{
1625 if(getParent()) {
1626 return getParent()->getWindowHandle() == hwndParent;
1627 }
1628 else return 0;
1629}
1630//******************************************************************************
1631//******************************************************************************
1632HWND Win32Window::GetTopWindow()
1633{
1634 return GetWindow(GW_CHILD);
1635}
1636//******************************************************************************
1637//Don't call WinUpdateWindow as that one also updates the child windows
1638//Also need to send WM_PAINT directly to the window procedure, which doesn't
1639//always happen with WinUpdateWindow (could be posted if thread doesn't own window)
1640//******************************************************************************
1641BOOL Win32Window::UpdateWindow()
1642{
1643 RECT rect;
1644
1645 if(OSLibWinQueryUpdateRect(OS2Hwnd, &rect))
1646 {//update region not empty
1647 SendInternalMessageA((isIcon) ? WM_PAINTICON : WM_PAINT, 0, 0);
1648 }
1649 return TRUE;
1650}
1651//******************************************************************************
1652//******************************************************************************
1653BOOL Win32Window::IsIconic()
1654{
1655 return OSLibWinIsIconic(OS2Hwnd);
1656}
1657//******************************************************************************
1658//TODO: not complete nor correct (distinction between top-level, top-most & child windows)
1659//******************************************************************************
1660HWND Win32Window::GetWindow(UINT uCmd)
1661{
1662 Win32Window *win32wnd;
1663 ULONG magic;
1664 ULONG getcmd = 0;
1665 HWND hwndRelated;
1666
1667 dprintf(("GetWindow %x %d NOT COMPLETE", getWindowHandle(), uCmd));
1668 switch(uCmd)
1669 {
1670 case GW_CHILD:
1671 getcmd = QWOS_TOP;
1672 break;
1673 case GW_HWNDFIRST:
1674 if(getParent()) {
1675 getcmd = QWOS_TOP; //top of child windows
1676 }
1677 else getcmd = QWOS_TOP; //TODO
1678 break;
1679 case GW_HWNDLAST:
1680 if(getParent()) {
1681 getcmd = QWOS_BOTTOM; //bottom of child windows
1682 }
1683 else getcmd = QWOS_BOTTOM; //TODO
1684 break;
1685 case GW_HWNDNEXT:
1686 getcmd = QWOS_NEXT;
1687 break;
1688 case GW_HWNDPREV:
1689 getcmd = QWOS_PREV;
1690 break;
1691 case GW_OWNER:
1692 if(owner) {
1693 return owner->getWindowHandle();
1694 }
1695 else return 0;
1696 }
1697 hwndRelated = OSLibWinQueryWindow(OS2Hwnd, getcmd);
1698 if(hwndRelated)
1699 {
1700 win32wnd = (Win32Window *)OSLibWinGetWindowULong(hwndRelated, OFFSET_WIN32WNDPTR);
1701 magic = OSLibWinGetWindowULong(hwndRelated, OFFSET_WIN32PM_MAGIC);
1702 if(CheckMagicDword(magic) && win32wnd)
1703 {
1704 return win32wnd->getWindowHandle();
1705 }
1706 }
1707 return 0;
1708}
1709//******************************************************************************
1710//******************************************************************************
1711HWND Win32Window::SetActiveWindow()
1712{
1713 return OSLibWinSetActiveWindow(OS2Hwnd);
1714}
1715//******************************************************************************
1716//WM_ENABLE is sent to hwnd, but not to it's children (as it should be)
1717//******************************************************************************
1718BOOL Win32Window::EnableWindow(BOOL fEnable)
1719{
1720 return OSLibWinEnableWindow(OS2Hwnd, fEnable);
1721}
1722//******************************************************************************
1723//******************************************************************************
1724BOOL Win32Window::CloseWindow()
1725{
1726 return OSLibWinMinimizeWindow(OS2Hwnd);
1727}
1728//******************************************************************************
1729//******************************************************************************
1730HWND Win32Window::GetActiveWindow()
1731{
1732 HWND hwndActive;
1733 Win32Window *win32wnd;
1734 ULONG magic;
1735
1736 hwndActive = OSLibWinQueryActiveWindow();
1737
1738 win32wnd = (Win32Window *)OSLibWinGetWindowULong(hwndActive, OFFSET_WIN32WNDPTR);
1739 magic = OSLibWinGetWindowULong(hwndActive, OFFSET_WIN32PM_MAGIC);
1740 if(CheckMagicDword(magic) && win32wnd)
1741 {
1742 return win32wnd->getWindowHandle();
1743 }
1744 return hwndActive;
1745}
1746//******************************************************************************
1747//******************************************************************************
1748BOOL Win32Window::IsWindow()
1749{
1750 return TRUE;
1751}
1752//******************************************************************************
1753//******************************************************************************
1754BOOL Win32Window::IsWindowEnabled()
1755{
1756 return OSLibWinIsWindowEnabled(OS2Hwnd);
1757}
1758//******************************************************************************
1759//******************************************************************************
1760BOOL Win32Window::IsWindowVisible()
1761{
1762 return OSLibWinIsWindowVisible(OS2Hwnd);
1763}
1764//******************************************************************************
1765//******************************************************************************
1766BOOL Win32Window::GetWindowRect(PRECT pRect)
1767{
1768 return OSLibWinQueryWindowRect(OS2Hwnd, pRect, RELATIVE_TO_SCREEN);
1769}
1770//******************************************************************************
1771//******************************************************************************
1772int Win32Window::GetWindowTextLengthA()
1773{
1774 return OSLibWinQueryWindowTextLength(OS2Hwnd);
1775}
1776//******************************************************************************
1777//******************************************************************************
1778int Win32Window::GetWindowTextA(LPSTR lpsz, int cch)
1779{
1780 return OSLibWinQueryWindowText(OS2Hwnd, cch, lpsz);
1781}
1782//******************************************************************************
1783//******************************************************************************
1784BOOL Win32Window::SetWindowTextA(LPCSTR lpsz)
1785{
1786 return OSLibWinSetWindowText(OS2Hwnd, (LPSTR)lpsz);
1787}
1788//******************************************************************************
1789//******************************************************************************
1790LONG Win32Window::SetWindowLongA(int index, ULONG value)
1791{
1792 LONG oldval;
1793
1794 switch(index) {
1795 case GWL_EXSTYLE:
1796 oldval = dwExStyle;
1797 dwExStyle = value;
1798 return oldval;
1799 case GWL_STYLE:
1800 oldval = dwStyle;
1801 dwStyle = value;
1802 return oldval;
1803 case GWL_WNDPROC:
1804 oldval = (LONG)getWindowProc();
1805 setWindowProc((WNDPROC)value);
1806 return oldval;
1807 case GWL_HINSTANCE:
1808 oldval = hInstance;
1809 hInstance = value;
1810 return oldval;
1811 case GWL_HWNDPARENT:
1812 return SetParent((HWND)value);
1813
1814 case GWL_ID:
1815 oldval = getWindowId();
1816 setWindowId(value);
1817 return oldval;
1818 case GWL_USERDATA:
1819 oldval = userData;
1820 userData = value;
1821 return oldval;
1822 default:
1823 if(index >= 0 && index/4 < nrUserWindowLong)
1824 {
1825 oldval = userWindowLong[index/4];
1826 userWindowLong[index/4] = value;
1827 return oldval;
1828 }
1829 SetLastError(ERROR_INVALID_PARAMETER);
1830 return 0;
1831 }
1832}
1833//******************************************************************************
1834//******************************************************************************
1835ULONG Win32Window::GetWindowLongA(int index)
1836{
1837 switch(index) {
1838 case GWL_EXSTYLE:
1839 return dwExStyle;
1840 case GWL_STYLE:
1841 return dwStyle;
1842 case GWL_WNDPROC:
1843 return (ULONG)getWindowProc();
1844 case GWL_HINSTANCE:
1845 return hInstance;
1846 case GWL_HWNDPARENT:
1847 if(getParent()) {
1848 return getParent()->getWindowHandle();
1849 }
1850 else return 0;
1851 case GWL_ID:
1852 return getWindowId();
1853 case GWL_USERDATA:
1854 return userData;
1855 default:
1856 if(index >= 0 && index/4 < nrUserWindowLong)
1857 {
1858 return userWindowLong[index/4];
1859 }
1860 SetLastError(ERROR_INVALID_PARAMETER);
1861 return 0;
1862 }
1863}
1864//******************************************************************************
1865//******************************************************************************
1866WORD Win32Window::SetWindowWord(int index, WORD value)
1867{
1868 WORD oldval;
1869
1870 if(index >= 0 && index/4 < nrUserWindowLong)
1871 {
1872 oldval = ((WORD *)userWindowLong)[index/2];
1873 ((WORD *)userWindowLong)[index/2] = value;
1874 return oldval;
1875 }
1876 SetLastError(ERROR_INVALID_PARAMETER);
1877 return 0;
1878}
1879//******************************************************************************
1880//******************************************************************************
1881WORD Win32Window::GetWindowWord(int index)
1882{
1883 if(index >= 0 && index/4 < nrUserWindowLong)
1884 {
1885 return ((WORD *)userWindowLong)[index/2];
1886 }
1887 SetLastError(ERROR_INVALID_PARAMETER);
1888 return 0;
1889}
1890//******************************************************************************
1891//******************************************************************************
1892Win32Window *Win32Window::GetWindowFromHandle(HWND hwnd)
1893{
1894 Win32Window *window;
1895
1896 if(HIWORD(hwnd) != 0x6800) {
1897 return NULL;
1898 }
1899
1900 if(HMHandleTranslateToOS2(LOWORD(hwnd), (PULONG)&window) == NO_ERROR) {
1901 return window;
1902 }
1903 else return NULL;
1904}
1905//******************************************************************************
1906//******************************************************************************
1907Win32Window *Win32Window::GetWindowFromOS2Handle(HWND hwnd)
1908{
1909 Win32Window *win32wnd;
1910 DWORD magic;
1911
1912 win32wnd = (Win32Window *)OSLibWinGetWindowULong(hwnd, OFFSET_WIN32WNDPTR);
1913 magic = OSLibWinGetWindowULong(hwnd, OFFSET_WIN32PM_MAGIC);
1914
1915 if(win32wnd && CheckMagicDword(magic)) {
1916 return win32wnd;
1917 }
1918 return 0;
1919}
1920//******************************************************************************
1921//******************************************************************************
1922GenericObject *Win32Window::windows = NULL;
Note: See TracBrowser for help on using the repository browser.