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

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

Lots of changes; Solitaire now starts

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