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

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

Lots of changes again

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