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

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

Property fixes, set last error when window creation fails

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