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

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

pmframe finished

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