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

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

Lots of changes

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