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

Last change on this file since 1192 was 1189, checked in by cbratschi, 26 years ago

subclassed frame, WM_STYLECHANGING fix

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