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

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

new window size/move code

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