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

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

Desktop enable bugfix + CTLCOLOR Wine port

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