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

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

Desktop window lookup bugfix

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