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

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

Clipboard fixes + EB's accelerator fix

File size: 88.7 KB
Line 
1/* $Id: win32wbase.cpp,v 1.32 1999-10-09 09:45:27 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 // this fit not really windows behavior.
914 // maybe TranslateAccelerator() is better
915 dprintf(("accelerator command"));
916 return SendInternalMessageA(WM_COMMAND, MAKELONG(Id, 0), 0);
917 }
918 return 0;
919}
920//******************************************************************************
921//******************************************************************************
922ULONG Win32BaseWindow::MsgHitTest(ULONG x, ULONG y)
923{
924 lastHitTestVal = SendInternalMessageA(WM_NCHITTEST, 0, MAKELONG((USHORT)x, (USHORT)y));
925 return 1; //TODO: May need to change this
926}
927//******************************************************************************
928//TODO: Send WM_NCCALCSIZE message here and correct size if necessary
929//******************************************************************************
930ULONG Win32BaseWindow::MsgSize(ULONG width, ULONG height, BOOL fMinimize, BOOL fMaximize)
931{
932 WORD fwSizeType = 0;
933
934 if(fCreated == FALSE) {//Solitaire crashes if it receives a WM_SIZE during CreateWindowEx (normal or our fault?)
935 return 1;
936 }
937
938 if(fMinimize) {
939 fwSizeType = SIZE_MINIMIZED;
940 }
941 else
942 if(fMaximize) {
943 fwSizeType = SIZE_MAXIMIZED;
944 }
945 else fwSizeType = SIZE_RESTORED;
946
947 return SendInternalMessageA(WM_SIZE, fwSizeType, MAKELONG((USHORT)width, (USHORT)height));
948}
949//******************************************************************************
950//******************************************************************************
951ULONG Win32BaseWindow::MsgActivate(BOOL fActivate, BOOL fMinimized, HWND hwnd)
952{
953 ULONG rc, curprocid, procidhwnd = -1, threadidhwnd = 0;
954
955 //According to SDK docs, if app returns FALSE & window is being deactivated,
956 //default processing is cancelled
957 //TODO: According to Wine we should proceed anyway if window is sysmodal
958 if(SendInternalMessageA(WM_NCACTIVATE, fActivate, 0) == FALSE && !fActivate)
959 {
960 return 0;
961 }
962 rc = SendInternalMessageA(WM_ACTIVATE, MAKELONG((fActivate) ? WA_ACTIVE : WA_INACTIVE, fMinimized), hwnd);
963
964 curprocid = GetCurrentProcessId();
965 if(hwnd) {
966 threadidhwnd = GetWindowThreadProcessId(hwnd, &procidhwnd);
967 }
968
969 if(curprocid != procidhwnd && fActivate) {
970 SendInternalMessageA(WM_ACTIVATEAPP, 1, threadidhwnd);
971 }
972 return rc;
973}
974//******************************************************************************
975//******************************************************************************
976ULONG Win32BaseWindow::MsgSysCommand(ULONG win32sc, ULONG x, ULONG y)
977{
978 return SendInternalMessageA(WM_SYSCOMMAND, win32sc, MAKELONG((USHORT)x, (USHORT)y));
979}
980//******************************************************************************
981//TODO: Is this correct and complete?
982//Add print screen, break & numlock
983//******************************************************************************
984void Win32BaseWindow::setExtendedKey(ULONG virtualkey, ULONG *lParam)
985{
986 switch(virtualkey) {
987 case VK_DOWN:
988 case VK_UP:
989 case VK_PRIOR:
990 case VK_NEXT:
991 case VK_END:
992 case VK_DIVIDE:
993 case VK_DELETE:
994 case VK_EXECUTE: //Numeric enter key?
995 case VK_HOME:
996 case VK_INSERT:
997 case VK_RCONTROL:
998 case VK_RMENU: //is this the right alt???
999 *lParam = *lParam | (1<<24);
1000 }
1001}
1002//******************************************************************************
1003//TODO: virtual key & (possibly) scancode translation, extended keyboard bit & Unicode
1004//******************************************************************************
1005ULONG Win32BaseWindow::MsgChar(ULONG cmd, ULONG repeatcnt, ULONG scancode, ULONG vkey, ULONG keyflags)
1006{
1007 ULONG lParam = 0;
1008
1009 lParam = repeatcnt;
1010 lParam |= (scancode << 16);
1011 setExtendedKey(vkey, &lParam);
1012
1013 if(keyflags & KEY_ALTDOWN)
1014 lParam |= (1<<29);
1015 if(keyflags & KEY_PREVDOWN)
1016 lParam |= (1<<30);
1017 if(keyflags & KEY_UP)
1018 lParam |= (1<<31);
1019 if(keyflags & KEY_DEADKEY) {
1020 dprintf(("WM_DEADCHAR: %x %x %08x", OS2Hwnd, cmd, lParam));
1021 return SendInternalMessageA(WM_DEADCHAR, cmd, lParam);
1022 }
1023 else {
1024 dprintf(("WM_CHAR: %x %x %08x", OS2Hwnd, cmd, lParam));
1025 return SendInternalMessageA(WM_CHAR, cmd, lParam);
1026 }
1027}
1028//******************************************************************************
1029//******************************************************************************
1030ULONG Win32BaseWindow::MsgKeyUp (ULONG repeatCount, ULONG scancode, ULONG virtualKey)
1031{
1032 ULONG lParam=0;
1033
1034 lParam = repeatCount & 0x0FFFF; // bit 0-15, repeatcount
1035 lParam |= (scancode & 0x0FF) << 16; // bit 16-23, scancode
1036 // bit 24, 1=extended key
1037 // bit 25-28, reserved
1038 lParam |= 0 << 29; // bit 29, key is released, always 0 for WM_KEYUP ?? <- conflict according to the MS docs
1039 lParam |= 1 << 30; // bit 30, previous state, always 1 for a WM_KEYUP message
1040 lParam |= 1 << 31; // bit 31, transition state, always 1 for WM_KEYUP
1041
1042 dprintf(("WM_KEYUP: vkey:(%x) param:(%x)", virtualKey, lParam));
1043
1044 setExtendedKey(virtualKey, &lParam);
1045 return SendInternalMessageA (WM_KEYUP, virtualKey, lParam);
1046}
1047//******************************************************************************
1048//******************************************************************************
1049ULONG Win32BaseWindow::MsgKeyDown (ULONG repeatCount, ULONG scancode, ULONG virtualKey, BOOL keyWasPressed)
1050{
1051 ULONG lParam=0;
1052
1053 lParam = repeatCount & 0x0FFFF; // bit 0-15, repeatcount
1054 lParam |= (scancode & 0x0FF) << 16; // bit 16-23, scancode
1055 // bit 24, 1=extended key
1056 // bit 25-28, reserved
1057 // bit 29, key is pressed, always 0 for WM_KEYDOWN ?? <- conflict according to the MS docs
1058 if (keyWasPressed)
1059 lParam |= 1 << 30; // bit 30, previous state, 1 means key was pressed
1060 // bit 31, transition state, always 0 for WM_KEYDOWN
1061
1062 setExtendedKey(virtualKey, &lParam);
1063
1064 dprintf(("WM_KEYDOWN: vkey:(%x) param:(%x)", virtualKey, lParam));
1065
1066 return SendInternalMessageA (WM_KEYDOWN, virtualKey, lParam);
1067}
1068//******************************************************************************
1069//******************************************************************************
1070ULONG Win32BaseWindow::MsgSysKeyUp (ULONG repeatCount, ULONG scancode, ULONG virtualKey)
1071{
1072 ULONG lParam=0;
1073
1074 lParam = repeatCount & 0x0FFFF; // bit 0-15,repeatcount
1075 lParam |= (scancode & 0x0FF) << 16; // bit 16-23, scancode
1076 // bit 24, 1=extended key
1077 // bit 25-28, reserved
1078 lParam |= 0 << 29; // bit 29, key is released, always 0 for WM_KEYUP ?? <- conflict according to the MS docs
1079 lParam |= 1 << 30; // bit 30, previous state, always 1 for a WM_KEYUP message
1080 lParam |= 1 << 31; // bit 31, transition state, always 1 for WM_KEYUP
1081
1082 setExtendedKey(virtualKey, &lParam);
1083 dprintf(("WM_SYSKEYUP: vkey:(%x) param:(%x)", virtualKey, lParam));
1084
1085 return SendInternalMessageA (WM_SYSKEYUP, virtualKey, lParam);
1086}
1087//******************************************************************************
1088//******************************************************************************
1089ULONG Win32BaseWindow::MsgSysKeyDown (ULONG repeatCount, ULONG scancode, ULONG virtualKey, BOOL keyWasPressed)
1090{
1091 ULONG lParam=0;
1092
1093 lParam = repeatCount & 0x0FFFF; // bit 0-15, repeatcount
1094 lParam |= (scancode & 0x0FF) << 16; // bit 16-23, scancode
1095 // bit 24, 1=extended key
1096 // bit 25-28, reserved
1097 // bit 29, key is pressed, always 0 for WM_KEYDOWN ?? <- conflict according to the MS docs
1098 if (keyWasPressed)
1099 lParam |= 1 << 30; // bit 30, previous state, 1 means key was pressed
1100 // bit 31, transition state, always 0 for WM_KEYDOWN
1101
1102 setExtendedKey(virtualKey, &lParam);
1103 dprintf(("WM_SYSKEYDOWN: vkey:(%x) param:(%x)", virtualKey, lParam));
1104
1105 return SendInternalMessageA (WM_SYSKEYDOWN, virtualKey, lParam);
1106}
1107//******************************************************************************
1108//******************************************************************************
1109ULONG Win32BaseWindow::MsgSetFocus(HWND hwnd)
1110{
1111 return SendInternalMessageA(WM_SETFOCUS, hwnd, 0);
1112}
1113//******************************************************************************
1114//******************************************************************************
1115ULONG Win32BaseWindow::MsgKillFocus(HWND hwnd)
1116{
1117 return SendInternalMessageA(WM_KILLFOCUS, hwnd, 0);
1118}
1119//******************************************************************************
1120//******************************************************************************
1121//******************************************************************************
1122ULONG Win32BaseWindow::MsgButton(ULONG msg, ULONG ncx, ULONG ncy, ULONG clx, ULONG cly)
1123{
1124 ULONG win32msg;
1125 ULONG win32ncmsg;
1126
1127 dprintf(("MsgButton to (%d,%d)", ncx, ncy));
1128 switch(msg) {
1129 case BUTTON_LEFTDOWN:
1130 win32msg = WM_LBUTTONDOWN;
1131 win32ncmsg = WM_NCLBUTTONDOWN;
1132 break;
1133 case BUTTON_LEFTUP:
1134 win32msg = WM_LBUTTONUP;
1135 win32ncmsg = WM_NCLBUTTONUP;
1136 break;
1137 case BUTTON_LEFTDBLCLICK:
1138 if (windowClass->getClassLongA(GCL_STYLE) & CS_DBLCLKS)
1139 {
1140 win32msg = WM_LBUTTONDBLCLK;
1141 win32ncmsg = WM_NCLBUTTONDBLCLK;
1142 } else
1143 {
1144 MsgButton(BUTTON_LEFTDOWN,ncx,ncy,clx,cly);
1145 return MsgButton(BUTTON_LEFTUP,ncx,ncy,clx,cly);
1146 }
1147 break;
1148 case BUTTON_RIGHTUP:
1149 win32msg = WM_RBUTTONUP;
1150 win32ncmsg = WM_NCRBUTTONUP;
1151 break;
1152 case BUTTON_RIGHTDOWN:
1153 win32msg = WM_RBUTTONDOWN;
1154 win32ncmsg = WM_NCRBUTTONDOWN;
1155 break;
1156 case BUTTON_RIGHTDBLCLICK:
1157 if (windowClass->getClassLongA(GCL_STYLE) & CS_DBLCLKS)
1158 {
1159 win32msg = WM_RBUTTONDBLCLK;
1160 win32ncmsg = WM_NCRBUTTONDBLCLK;
1161 } else
1162 {
1163 MsgButton(BUTTON_RIGHTDOWN,ncx,ncy,clx,cly);
1164 return MsgButton(BUTTON_RIGHTUP,ncx,ncy,clx,cly);
1165 }
1166 break;
1167 case BUTTON_MIDDLEUP:
1168 win32msg = WM_MBUTTONUP;
1169 win32ncmsg = WM_NCMBUTTONUP;
1170 break;
1171 case BUTTON_MIDDLEDOWN:
1172 win32msg = WM_MBUTTONDOWN;
1173 win32ncmsg = WM_NCMBUTTONDOWN;
1174 break;
1175 case BUTTON_MIDDLEDBLCLICK:
1176 if (windowClass->getClassLongA(GCL_STYLE) & CS_DBLCLKS)
1177 {
1178 win32msg = WM_MBUTTONDBLCLK;
1179 win32ncmsg = WM_NCMBUTTONDBLCLK;
1180 } else
1181 {
1182 MsgButton(BUTTON_MIDDLEDOWN,ncx,ncy,clx,cly);
1183 return MsgButton(BUTTON_MIDDLEUP,ncx,ncy,clx,cly);
1184 }
1185 break;
1186 default:
1187 dprintf(("Win32BaseWindow::Button: invalid msg!!!!"));
1188 return 1;
1189 }
1190
1191 SendInternalMessageA(WM_SETCURSOR, Win32Hwnd, MAKELONG(lastHitTestVal, win32ncmsg));
1192
1193 //WM_NC*BUTTON* is posted when the cursor is in a non-client area of the window
1194 if(lastHitTestVal != HTCLIENT) {
1195 return SendInternalMessageA(win32ncmsg, lastHitTestVal, MAKELONG(ncx, ncy)); //TODO:
1196 }
1197 return SendInternalMessageA(win32msg, 0, MAKELONG(clx, cly));
1198}
1199//******************************************************************************
1200//******************************************************************************
1201ULONG Win32BaseWindow::MsgMouseMove(ULONG keystate, ULONG x, ULONG y)
1202{
1203 ULONG winstate = 0;
1204 ULONG setcursormsg = WM_MOUSEMOVE;
1205
1206 if(keystate & WMMOVE_LBUTTON)
1207 winstate |= MK_LBUTTON;
1208 if(keystate & WMMOVE_RBUTTON)
1209 winstate |= MK_RBUTTON;
1210 if(keystate & WMMOVE_MBUTTON)
1211 winstate |= MK_MBUTTON;
1212 if(keystate & WMMOVE_SHIFT)
1213 winstate |= MK_SHIFT;
1214 if(keystate & WMMOVE_CTRL)
1215 winstate |= MK_CONTROL;
1216
1217 if(lastHitTestVal != HTCLIENT) {
1218 setcursormsg = WM_NCMOUSEMOVE;
1219 }
1220 //TODO: hiword should be 0 if window enters menu mode (SDK docs)
1221 SendInternalMessageA(WM_SETCURSOR, Win32Hwnd, MAKELONG(lastHitTestVal, setcursormsg));
1222
1223 //WM_NCMOUSEMOVE is posted when the cursor moves into a non-client area of the window
1224 if(lastHitTestVal != HTCLIENT) {
1225 SendInternalMessageA(WM_NCMOUSEMOVE, lastHitTestVal, MAKELONG(x, y));
1226 }
1227 return SendInternalMessageA(WM_MOUSEMOVE, keystate, MAKELONG(x, y));
1228}
1229//******************************************************************************
1230//******************************************************************************
1231ULONG Win32BaseWindow::MsgPaint(ULONG tmp1, BOOL select)
1232{
1233 if (select && isIcon)
1234 return SendInternalMessageA(WM_PAINTICON, 0, 0);
1235 else
1236 return SendInternalMessageA(WM_PAINT, 0, 0);
1237}
1238//******************************************************************************
1239//TODO: Is the clipper region of the window DC equal to the invalidated rectangle?
1240// (or are we simply erasing too much here)
1241//******************************************************************************
1242ULONG Win32BaseWindow::MsgEraseBackGround(HDC hdc)
1243{
1244 ULONG rc;
1245 HDC hdcErase = hdc;
1246
1247 if (hdcErase == 0)
1248 hdcErase = O32_GetDC(OS2Hwnd);
1249
1250 if(isIcon)
1251 rc = SendInternalMessageA(WM_ICONERASEBKGND, hdcErase, 0);
1252 else
1253 rc = SendInternalMessageA(WM_ERASEBKGND, hdcErase, 0);
1254 if (hdc == 0)
1255 O32_ReleaseDC(OS2Hwnd, hdcErase);
1256 return (rc);
1257}
1258//******************************************************************************
1259//******************************************************************************
1260ULONG Win32BaseWindow::MsgSetText(LPSTR lpsz, LONG cch)
1261{
1262 if(isUnicode) {
1263 return SendInternalMessageW(WM_SETTEXT, 0, (LPARAM)lpsz);
1264 }
1265 else return SendInternalMessageA(WM_SETTEXT, 0, (LPARAM)lpsz);
1266}
1267//******************************************************************************
1268//TODO: in- or excluding terminating 0?
1269//******************************************************************************
1270ULONG Win32BaseWindow::MsgGetTextLength()
1271{
1272 return SendInternalMessageA(WM_GETTEXTLENGTH, 0, 0);
1273}
1274//******************************************************************************
1275//******************************************************************************
1276char *Win32BaseWindow::MsgGetText()
1277{
1278 if(isUnicode) {
1279 SendInternalMessageW(WM_GETTEXT, wndNameLength, (LPARAM)windowNameW);
1280 }
1281 else {
1282 SendInternalMessageA(WM_GETTEXT, wndNameLength, (LPARAM)windowNameA);
1283 }
1284 return windowNameA;
1285}
1286//******************************************************************************
1287//******************************************************************************
1288BOOL Win32BaseWindow::isMDIClient()
1289{
1290 return FALSE;
1291}
1292//******************************************************************************
1293//TODO: Not complete (flags)
1294//******************************************************************************
1295SCROLLBAR_INFO *Win32BaseWindow::getScrollInfo(int nBar)
1296{
1297 switch(nBar) {
1298 case SB_HORZ:
1299 if(horzScrollInfo) {
1300 horzScrollInfo->CurVal = OSLibWinGetScrollPos(OS2HwndFrame, hwndHorzScroll);
1301 return horzScrollInfo;
1302 }
1303 break;
1304 case SB_VERT:
1305 if(vertScrollInfo) {
1306 vertScrollInfo->CurVal = OSLibWinGetScrollPos(OS2HwndFrame, hwndVertScroll);
1307 return vertScrollInfo;
1308 }
1309 break;
1310 }
1311 return NULL;
1312}
1313//******************************************************************************
1314//TODO: Not complete
1315//******************************************************************************
1316LONG Win32BaseWindow::setScrollInfo(int nBar, SCROLLINFO *info, int fRedraw)
1317{
1318 SCROLLBAR_INFO *infoPtr;
1319 HWND hwndScroll;
1320 ULONG scrollType;
1321 int new_flags;
1322
1323 switch(nBar) {
1324 case SB_HORZ:
1325 if(!horzScrollInfo) {
1326 return 0;
1327 }
1328 infoPtr = horzScrollInfo;
1329 hwndScroll = hwndHorzScroll;
1330 scrollType = OSLIB_HSCROLL;
1331 break;
1332 case SB_VERT:
1333 if(!vertScrollInfo) {
1334 return 0;
1335 }
1336 infoPtr = vertScrollInfo;
1337 hwndScroll = hwndVertScroll;
1338 scrollType = OSLIB_VSCROLL;
1339 break;
1340 default:
1341 return 0;
1342 }
1343
1344 if (info->fMask & ~(SIF_ALL | SIF_DISABLENOSCROLL)) return 0;
1345 if ((info->cbSize != sizeof(*info)) &&
1346 (info->cbSize != sizeof(*info)-sizeof(info->nTrackPos))) return 0;
1347
1348 /* Set the page size */
1349 if (info->fMask & SIF_PAGE)
1350 {
1351 if( infoPtr->Page != info->nPage )
1352 {
1353 infoPtr->Page = info->nPage;
1354 OSLibWinSetScrollPageSize(OS2HwndFrame, hwndScroll, info->nPage, infoPtr->MaxVal, fRedraw);
1355 }
1356 }
1357
1358 /* Set the scroll pos */
1359 if (info->fMask & SIF_POS)
1360 {
1361 if( infoPtr->CurVal != info->nPos )
1362 {
1363 infoPtr->CurVal = info->nPos;
1364 OSLibWinSetScrollPos(OS2HwndFrame, hwndScroll, info->nPos, fRedraw);
1365 }
1366 }
1367
1368 /* Set the scroll range */
1369 if (info->fMask & SIF_RANGE)
1370 {
1371 /* Invalid range -> range is set to (0,0) */
1372 if ((info->nMin > info->nMax) ||
1373 ((UINT)(info->nMax - info->nMin) >= 0x80000000))
1374 {
1375 infoPtr->MinVal = 0;
1376 infoPtr->MaxVal = 0;
1377 }
1378 else
1379 {
1380 if( infoPtr->MinVal != info->nMin ||
1381 infoPtr->MaxVal != info->nMax )
1382 {
1383 infoPtr->MinVal = info->nMin;
1384 infoPtr->MaxVal = info->nMax;
1385
1386 OSLibWinSetScrollRange(OS2HwndFrame, hwndScroll, info->nMin, info->nMax, fRedraw);
1387 }
1388 }
1389 }
1390
1391 /* Make sure the page size is valid */
1392 if (infoPtr->Page < 0) infoPtr->Page = 0;
1393 else if (infoPtr->Page > infoPtr->MaxVal - infoPtr->MinVal + 1 )
1394 infoPtr->Page = infoPtr->MaxVal - infoPtr->MinVal + 1;
1395
1396 /* Make sure the pos is inside the range */
1397 if (infoPtr->CurVal < infoPtr->MinVal)
1398 infoPtr->CurVal = infoPtr->MinVal;
1399 else if (infoPtr->CurVal > infoPtr->MaxVal - MAX( infoPtr->Page-1, 0 ))
1400 infoPtr->CurVal = infoPtr->MaxVal - MAX( infoPtr->Page-1, 0 );
1401
1402 /* Check if the scrollbar should be hidden or disabled */
1403 if (info->fMask & (SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL))
1404 {
1405 new_flags = infoPtr->flags;
1406 if (infoPtr->MinVal >= infoPtr->MaxVal - MAX( infoPtr->Page-1, 0 ))
1407 {
1408 /* Hide or disable scroll-bar */
1409 if (info->fMask & SIF_DISABLENOSCROLL)
1410 {
1411 new_flags = ESB_DISABLE_BOTH;
1412 //TODO:
1413 }
1414 else if (nBar != SB_CTL)
1415 {
1416 //TODO
1417 goto done;
1418 }
1419 }
1420 else /* Show and enable scroll-bar */
1421 {
1422 //TODO
1423 new_flags = 0;
1424 }
1425
1426 if (infoPtr->flags != new_flags) /* check arrow flags */
1427 {
1428 infoPtr->flags = new_flags;
1429 }
1430 }
1431
1432done:
1433 /* Return current position */
1434
1435 return infoPtr->CurVal;
1436}
1437//******************************************************************************
1438//******************************************************************************
1439LRESULT Win32BaseWindow::DefWindowProcA(UINT Msg, WPARAM wParam, LPARAM lParam)
1440{
1441 switch(Msg)
1442 {
1443 case WM_CLOSE:
1444 DestroyWindow();
1445 return 0;
1446
1447 case WM_GETTEXTLENGTH:
1448 return wndNameLength;
1449
1450 case WM_GETTEXT: //TODO: SS_ICON controls
1451 strncpy((LPSTR)lParam, windowNameA, wParam);
1452 return min(wndNameLength, wParam);
1453
1454 case WM_SETTEXT:
1455 if(!fInternalMsg) {
1456 return SetWindowTextA((LPSTR)lParam);
1457 }
1458 else return 0;
1459
1460 case WM_SETREDRAW:
1461 if(wParam)
1462 SetWindowLongA (GWL_STYLE, GetWindowLongA (GWL_STYLE) | WS_VISIBLE);
1463 else SetWindowLongA (GWL_STYLE, GetWindowLongA (GWL_STYLE) & ~WS_VISIBLE);
1464
1465 return 0; //TODO
1466
1467 case WM_NCCREATE:
1468 return(TRUE);
1469
1470 //SvL: Set background color to default button color (not window (white))
1471 case WM_CTLCOLORBTN:
1472 SetBkColor((HDC)wParam, GetSysColor(COLOR_BTNFACE));
1473 SetTextColor((HDC)wParam, GetSysColor(COLOR_WINDOWTEXT));
1474 return GetSysColorBrush(COLOR_BTNFACE);
1475
1476 //SvL: Set background color to default dialog color if window is dialog
1477 case WM_CTLCOLORDLG:
1478 case WM_CTLCOLORSTATIC:
1479 if(IsDialog()) {
1480 SetBkColor((HDC)wParam, GetSysColor(COLOR_BTNFACE));
1481 SetTextColor((HDC)wParam, GetSysColor(COLOR_WINDOWTEXT));
1482 return GetSysColorBrush(COLOR_BTNFACE);
1483 }
1484 //no break
1485
1486 case WM_CTLCOLORMSGBOX:
1487 case WM_CTLCOLOREDIT:
1488 case WM_CTLCOLORLISTBOX:
1489 case WM_CTLCOLORSCROLLBAR:
1490 SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW));
1491 SetTextColor((HDC)wParam, GetSysColor(COLOR_WINDOWTEXT));
1492 return GetSysColorBrush(COLOR_BTNFACE);
1493
1494 case WM_PARENTNOTIFY:
1495 return 0;
1496
1497 case WM_MOUSEACTIVATE:
1498 {
1499 DWORD dwStyle = GetWindowLongA(GWL_STYLE);
1500 DWORD dwExStyle = GetWindowLongA(GWL_EXSTYLE);
1501 dprintf(("DefWndProc: WM_MOUSEACTIVATE for %x Msg %s", Win32Hwnd, GetMsgText(HIWORD(lParam))));
1502 if(dwStyle & WS_CHILD && !(dwExStyle & WS_EX_NOPARENTNOTIFY) )
1503 {
1504 if(getParent()) {
1505 LRESULT rc = getParent()->SendMessageA(WM_MOUSEACTIVATE, wParam, lParam );
1506 if(rc) return rc;
1507 }
1508 }
1509 return (LOWORD(lParam) == HTCAPTION) ? MA_NOACTIVATE : MA_ACTIVATE;
1510 }
1511 case WM_SETCURSOR:
1512 {
1513 DWORD dwStyle = GetWindowLongA(GWL_STYLE);
1514 DWORD dwExStyle = GetWindowLongA(GWL_EXSTYLE);
1515 dprintf(("DefWndProc: WM_SETCURSOR for %x Msg %s", Win32Hwnd, GetMsgText(HIWORD(lParam))));
1516 if(dwStyle & WS_CHILD && !(dwExStyle & WS_EX_NOPARENTNOTIFY) )
1517 {
1518 if(getParent()) {
1519 LRESULT rc = getParent()->SendMessageA(WM_SETCURSOR, wParam, lParam);
1520 if(rc) return rc;
1521 }
1522 }
1523 return 1;
1524 }
1525 case WM_MOUSEMOVE:
1526 return 0;
1527
1528 case WM_WINDOWPOSCHANGED:
1529 {
1530
1531/* undocumented SWP flags - from SDK 3.1 */
1532#define SWP_NOCLIENTSIZE 0x0800
1533#define SWP_NOCLIENTMOVE 0x1000
1534
1535 PWINDOWPOS wpos = (PWINDOWPOS)lParam;
1536 WPARAM wp = SIZE_RESTORED;
1537
1538 if (!(wpos->flags & SWP_NOMOVE) && !(wpos->flags & SWP_NOCLIENTMOVE))
1539 SendMessageA(WM_MOVE, 0, MAKELONG(rectClient.left, rectClient.top));
1540
1541 if (!(wpos->flags & SWP_NOSIZE) && !(wpos->flags & SWP_NOCLIENTSIZE))
1542 {
1543 if (dwStyle & WS_MAXIMIZE) wp = SIZE_MAXIMIZED;
1544 else if (dwStyle & WS_MINIMIZE) wp = SIZE_MINIMIZED;
1545
1546 SendMessageA(WM_SIZE, wp, MAKELONG(rectClient.right - rectClient.left,
1547 rectClient.bottom - rectClient.top));
1548 }
1549 return 0;
1550 }
1551 case WM_ERASEBKGND:
1552 case WM_ICONERASEBKGND:
1553 {
1554 RECT rect;
1555 int rc;
1556
1557 if (!windowClass->getBackgroundBrush()) return 0;
1558
1559 rc = GetClipBox( (HDC)wParam, &rect );
1560 if ((rc == SIMPLEREGION) || (rc == COMPLEXREGION))
1561 FillRect( (HDC)wParam, &rect, windowClass->getBackgroundBrush());
1562
1563 return 1;
1564 }
1565 case WM_GETDLGCODE:
1566 return 0;
1567
1568 case WM_NCLBUTTONDOWN:
1569 case WM_NCLBUTTONUP:
1570 case WM_NCLBUTTONDBLCLK:
1571 case WM_NCRBUTTONUP:
1572 case WM_NCRBUTTONDOWN:
1573 case WM_NCRBUTTONDBLCLK:
1574 case WM_NCMBUTTONDOWN:
1575 case WM_NCMBUTTONUP:
1576 case WM_NCMBUTTONDBLCLK:
1577 return 0; //TODO: Send WM_SYSCOMMAND if required
1578
1579 case WM_NCHITTEST: //TODO: Calculate position of
1580 return HTCLIENT;
1581
1582#if 0
1583 case WM_SYSKEYDOWN:
1584 if(HIWORD(lParam) & KEYDATA_ALT)
1585 {
1586 if(wParam == VK_F4) /* try to close the window */
1587 {
1588 HWND hWnd = WIN_GetTopParent( wndPtr->hwndSelf );
1589 wndPtr = WIN_FindWndPtr( hWnd );
1590 if( wndPtr && !(getClass()->getStyle() & CS_NOCLOSE) )
1591 PostMessage(WM_SYSCOMMAND, SC_CLOSE, 0);
1592 }
1593 }
1594 return 0;
1595#endif
1596
1597 default:
1598 return 1;
1599 }
1600}
1601//******************************************************************************
1602//******************************************************************************
1603LRESULT Win32BaseWindow::DefWindowProcW(UINT Msg, WPARAM wParam, LPARAM lParam)
1604{
1605 switch(Msg)
1606 {
1607 case WM_GETTEXTLENGTH:
1608 return wndNameLength;
1609
1610 case WM_GETTEXT: //TODO: SS_ICON controls
1611 lstrcpynW((LPWSTR)lParam, windowNameW, wParam);
1612 return min(wndNameLength, wParam);
1613
1614 case WM_SETTEXT:
1615 if(!fInternalMsg) {
1616 return SetWindowTextW((LPWSTR)lParam);
1617 }
1618 else return 0;
1619
1620 default:
1621 return DefWindowProcA(Msg, wParam, lParam);
1622 }
1623}
1624//******************************************************************************
1625//******************************************************************************
1626LRESULT Win32BaseWindow::SendMessageA(ULONG Msg, WPARAM wParam, LPARAM lParam)
1627{
1628 LRESULT rc;
1629 BOOL fInternalMsgBackup = fInternalMsg;
1630
1631 if(Msg != WM_GETDLGCODE && Msg != WM_ENTERIDLE) {//sent *very* often
1632 if(PostSpyMessage(getWindowHandle(), Msg, wParam, lParam) == FALSE)
1633 dprintf(("SendMessageA %s for %x %x %x", GetMsgText(Msg), getWindowHandle(), wParam, lParam));
1634 }
1635
1636 if(HkCBT::OS2HkCBTProc(getWindowHandle(), Msg, wParam, lParam) == TRUE) {//hook swallowed msg
1637 return(0);
1638 }
1639 fInternalMsg = FALSE;
1640 switch(Msg)
1641 {
1642 case WM_CREATE:
1643 {
1644 if(win32wndproc(getWindowHandle(), WM_CREATE, 0, lParam) == -1) {
1645 dprintf(("WM_CREATE returned -1\n"));
1646 rc = -1; //don't create window
1647 break;
1648 }
1649 NotifyParent(Msg, wParam, lParam);
1650
1651 rc = 0;
1652 break;
1653 }
1654 case WM_SETTEXT:
1655 rc = win32wndproc(getWindowHandle(), WM_SETTEXT, wParam, lParam);
1656 break;
1657
1658 case WM_LBUTTONDOWN:
1659 case WM_MBUTTONDOWN:
1660 case WM_RBUTTONDOWN:
1661 NotifyParent(Msg, wParam, lParam);
1662 rc = win32wndproc(getWindowHandle(), Msg, wParam, lParam);
1663 break;
1664
1665 case WM_DESTROY:
1666 rc = win32wndproc(getWindowHandle(), WM_DESTROY, 0, 0);
1667 break;
1668
1669 default:
1670 rc = win32wndproc(getWindowHandle(), Msg, wParam, lParam);
1671 break;
1672 }
1673 fInternalMsg = fInternalMsgBackup;
1674 return rc;
1675}
1676//******************************************************************************
1677//******************************************************************************
1678LRESULT Win32BaseWindow::SendMessageW(ULONG Msg, WPARAM wParam, LPARAM lParam)
1679{
1680 LRESULT rc;
1681 BOOL fInternalMsgBackup = fInternalMsg;
1682
1683 if(Msg != WM_GETDLGCODE && Msg != WM_ENTERIDLE) {//sent *very* often
1684 if(PostSpyMessage(getWindowHandle(), Msg, wParam, lParam) == FALSE)
1685 dprintf(("SendMessageW %s for %x %x %x", GetMsgText(Msg), getWindowHandle(), wParam, lParam));
1686 }
1687
1688 if(HkCBT::OS2HkCBTProc(getWindowHandle(), Msg, wParam, lParam) == TRUE) {//hook swallowed msg
1689 return(0);
1690 }
1691 fInternalMsg = FALSE;
1692 switch(Msg)
1693 {
1694 case WM_CREATE:
1695 {
1696 if(win32wndproc(getWindowHandle(), WM_CREATE, 0, lParam) == -1) {
1697 dprintf(("WM_CREATE returned -1\n"));
1698 rc = -1; //don't create window
1699 break;
1700 }
1701 NotifyParent(Msg, wParam, lParam);
1702
1703 rc = 0;
1704 break;
1705 }
1706 case WM_SETTEXT:
1707 rc = win32wndproc(getWindowHandle(), WM_SETTEXT, wParam, lParam);
1708 break;
1709
1710 case WM_LBUTTONDOWN:
1711 case WM_MBUTTONDOWN:
1712 case WM_RBUTTONDOWN:
1713 NotifyParent(Msg, wParam, lParam);
1714 rc = win32wndproc(getWindowHandle(), Msg, wParam, lParam);
1715 break;
1716
1717 case WM_DESTROY:
1718 win32wndproc(getWindowHandle(), WM_NCDESTROY, 0, 0);
1719 NotifyParent(Msg, wParam, lParam);
1720 rc = win32wndproc(getWindowHandle(), WM_DESTROY, 0, 0);
1721 break;
1722
1723 default:
1724 rc = win32wndproc(getWindowHandle(), Msg, wParam, lParam);
1725 break;
1726 }
1727 fInternalMsg = fInternalMsgBackup;
1728 return rc;
1729}
1730//******************************************************************************
1731//Called as a result of an OS/2 message
1732//******************************************************************************
1733LRESULT Win32BaseWindow::SendInternalMessageA(ULONG Msg, WPARAM wParam, LPARAM lParam)
1734{
1735 LRESULT rc;
1736 BOOL fInternalMsgBackup = fInternalMsg;
1737
1738 if(PostSpyMessage(getWindowHandle(), Msg, wParam, lParam) == FALSE)
1739 dprintf(("SendInternalMessageA %s for %x %x %x", GetMsgText(Msg), getWindowHandle(), wParam, lParam));
1740
1741 if(HkCBT::OS2HkCBTProc(getWindowHandle(), Msg, wParam, lParam) == TRUE) {//hook swallowed msg
1742 return(0);
1743 }
1744 fInternalMsg = TRUE;
1745 switch(Msg)
1746 {
1747 case WM_CREATE:
1748 {
1749 if(win32wndproc(getWindowHandle(), WM_CREATE, 0, lParam) == -1) {
1750 dprintf(("WM_CREATE returned -1\n"));
1751 rc = -1; //don't create window
1752 break;
1753 }
1754 NotifyParent(Msg, wParam, lParam);
1755 rc = 0;
1756 break;
1757 }
1758 case WM_LBUTTONDOWN:
1759 case WM_MBUTTONDOWN:
1760 case WM_RBUTTONDOWN:
1761 NotifyParent(Msg, wParam, lParam);
1762 rc = win32wndproc(getWindowHandle(), Msg, wParam, lParam);
1763 break;
1764
1765 case WM_DESTROY:
1766 win32wndproc(getWindowHandle(), WM_NCDESTROY, 0, 0);
1767 NotifyParent(Msg, wParam, lParam);
1768 rc = win32wndproc(getWindowHandle(), WM_DESTROY, 0, 0);
1769 break;
1770 default:
1771 rc = win32wndproc(getWindowHandle(), Msg, wParam, lParam);
1772 break;
1773 }
1774 fInternalMsg = fInternalMsgBackup;
1775 return rc;
1776}
1777//******************************************************************************
1778//Called as a result of an OS/2 message
1779//todo, unicode msgs (WM_SETTEXT etc)
1780//******************************************************************************
1781LRESULT Win32BaseWindow::SendInternalMessageW(ULONG Msg, WPARAM wParam, LPARAM lParam)
1782{
1783 LRESULT rc;
1784 BOOL fInternalMsgBackup = fInternalMsg;
1785
1786 if(PostSpyMessage(getWindowHandle(), Msg, wParam, lParam) == FALSE)
1787 dprintf(("SendInternalMessageW %s for %x %x %x", GetMsgText(Msg), getWindowHandle(), wParam, lParam));
1788
1789 if(HkCBT::OS2HkCBTProc(getWindowHandle(), Msg, wParam, lParam) == TRUE) {//hook swallowed msg
1790 return(0);
1791 }
1792 fInternalMsg = TRUE;
1793 switch(Msg)
1794 {
1795 case WM_CREATE:
1796 {
1797 if(win32wndproc(getWindowHandle(), WM_CREATE, 0, lParam) == -1) {
1798 dprintf(("WM_CREATE returned -1\n"));
1799 rc = -1; //don't create window
1800 break;
1801 }
1802 NotifyParent(Msg, wParam, lParam);
1803 rc = 0;
1804 break;
1805 }
1806 case WM_LBUTTONDOWN:
1807 case WM_MBUTTONDOWN:
1808 case WM_RBUTTONDOWN:
1809 NotifyParent(Msg, wParam, lParam);
1810 rc = win32wndproc(getWindowHandle(), Msg, wParam, lParam);
1811 break;
1812
1813 case WM_DESTROY:
1814 win32wndproc(getWindowHandle(), WM_NCDESTROY, 0, 0);
1815 NotifyParent(Msg, wParam, lParam);
1816 rc = win32wndproc(getWindowHandle(), WM_DESTROY, 0, 0);
1817 break;
1818 default:
1819 rc = win32wndproc(getWindowHandle(), Msg, wParam, lParam);
1820 break;
1821 }
1822 fInternalMsg = fInternalMsgBackup;
1823 return rc;
1824}
1825//******************************************************************************
1826//******************************************************************************
1827BOOL Win32BaseWindow::PostMessageA(ULONG msg, WPARAM wParam, LPARAM lParam)
1828{
1829 return OSLibPostMessage(OS2Hwnd, WIN32APP_USERMSGBASE+msg, wParam, lParam);
1830}
1831//******************************************************************************
1832//******************************************************************************
1833BOOL Win32BaseWindow::PostMessageW(ULONG msg, WPARAM wParam, LPARAM lParam)
1834{
1835 return OSLibPostMessage(OS2Hwnd, WIN32APP_USERMSGBASE+msg, wParam, lParam);
1836}
1837//******************************************************************************
1838//TODO: do we need to inform the parent of the parent (etc) of the child window?
1839//******************************************************************************
1840void Win32BaseWindow::NotifyParent(UINT Msg, WPARAM wParam, LPARAM lParam)
1841{
1842 Win32BaseWindow *window = this;
1843 Win32BaseWindow *parentwindow;
1844
1845 while(window)
1846 {
1847 if(window->getStyle() & WS_CHILD && !(window->getExStyle() & WS_EX_NOPARENTNOTIFY) )
1848 {
1849 /* Notify the parent window only */
1850 parentwindow = window->getParent();
1851 if(parentwindow) {
1852 if(Msg == WM_CREATE || Msg == WM_DESTROY) {
1853 parentwindow->SendMessageA(WM_PARENTNOTIFY, MAKEWPARAM(Msg, window->getWindowId()), (LPARAM)window->getWindowHandle());
1854 }
1855 else parentwindow->SendMessageA(WM_PARENTNOTIFY, MAKEWPARAM(Msg, window->getWindowId()), lParam );
1856 }
1857 }
1858 else break;
1859
1860 window = parentwindow;
1861 }
1862}
1863//******************************************************************************
1864//******************************************************************************
1865Win32BaseWindow *Win32BaseWindow::getTopParent()
1866{
1867 Win32BaseWindow *tmpWnd = this;
1868
1869 while( tmpWnd && (tmpWnd->getStyle() & WS_CHILD))
1870 {
1871 tmpWnd = tmpWnd->getParent();
1872 }
1873 return tmpWnd;
1874}
1875//******************************************************************************
1876//******************************************************************************
1877BOOL Win32BaseWindow::SetMenu(HMENU hMenu)
1878{
1879
1880 dprintf(("SetMenu %x", hMenu));
1881 OS2HwndMenu = OSLibWinSetMenu(OS2HwndFrame, hMenu);
1882 if(OS2HwndMenu == 0) {
1883 dprintf(("Win32BaseWindow::SetMenu OS2HwndMenu == 0"));
1884 return FALSE;
1885 }
1886 return TRUE;
1887}
1888//******************************************************************************
1889//******************************************************************************
1890BOOL Win32BaseWindow::SetAccelTable(HACCEL hAccel)
1891{
1892 Win32Resource *winres = (Win32Resource *)hAccel;
1893 HANDLE accelhandle;
1894
1895 if(HIWORD(hAccel) == 0) {
1896 dprintf(("SetAccelTable: hAccel %x invalid", hAccel));
1897 SetLastError(ERROR_INVALID_PARAMETER);
1898 return FALSE;
1899 }
1900 acceltableResource = winres;
1901 accelhandle = OSLibWinSetAccelTable(OS2HwndFrame, winres->getOS2Handle(), winres->lockOS2Resource());
1902 winres->setOS2Handle(accelhandle);
1903 return(accelhandle != 0);
1904}
1905//******************************************************************************
1906//******************************************************************************
1907BOOL Win32BaseWindow::SetIcon(HICON hIcon)
1908{
1909 dprintf(("Win32BaseWindow::SetIcon %x", hIcon));
1910 if(OSLibWinSetIcon(OS2HwndFrame, hIcon) == TRUE) {
1911 SendMessageA(WM_SETICON, hIcon, 0);
1912 return TRUE;
1913 }
1914 return FALSE;
1915}
1916//******************************************************************************
1917//******************************************************************************
1918BOOL Win32BaseWindow::ShowWindow(ULONG nCmdShow)
1919{
1920 ULONG showstate = 0;
1921
1922 dprintf(("ShowWindow %x", nCmdShow));
1923 if(fFirstShow) {
1924 if(isFrameWindow() && IS_OVERLAPPED(getStyle())) {
1925 SendMessageA(WM_SIZE, SIZE_RESTORED,
1926 MAKELONG(rectClient.right-rectClient.left,
1927 rectClient.bottom-rectClient.top));
1928 SendMessageA(WM_MOVE, 0, MAKELONG( rectClient.left, rectClient.top ) );
1929
1930 }
1931 fFirstShow = FALSE;
1932 }
1933 switch(nCmdShow)
1934 {
1935 case SW_SHOW:
1936 case SW_SHOWDEFAULT: //todo
1937 showstate = SWPOS_SHOW | SWPOS_ACTIVATE;
1938 break;
1939 case SW_HIDE:
1940 showstate = SWPOS_HIDE;
1941 break;
1942 case SW_RESTORE:
1943 showstate = SWPOS_RESTORE | SWPOS_SHOW | SWPOS_ACTIVATE;
1944 break;
1945 case SW_MINIMIZE:
1946 showstate = SWPOS_MINIMIZE;
1947 break;
1948 case SW_SHOWMAXIMIZED:
1949 showstate = SWPOS_MAXIMIZE | SWPOS_SHOW | SWPOS_ACTIVATE;
1950 break;
1951 case SW_SHOWMINIMIZED:
1952 showstate = SWPOS_MINIMIZE | SWPOS_SHOW | SWPOS_ACTIVATE;
1953 break;
1954 case SW_SHOWMINNOACTIVE:
1955 showstate = SWPOS_MINIMIZE | SWPOS_SHOW;
1956 break;
1957 case SW_SHOWNA:
1958 showstate = SWPOS_SHOW;
1959 break;
1960 case SW_SHOWNOACTIVATE:
1961 showstate = SWPOS_SHOW;
1962 break;
1963 case SW_SHOWNORMAL:
1964 showstate = SWPOS_RESTORE | SWPOS_ACTIVATE | SWPOS_SHOW;
1965 break;
1966 }
1967 BOOL rc = OSLibWinShowWindow(OS2HwndFrame, showstate);
1968 return rc;
1969}
1970//******************************************************************************
1971//******************************************************************************
1972BOOL Win32BaseWindow::SetWindowPos(HWND hwndInsertAfter, int x, int y, int cx, int cy, UINT fuFlags)
1973{
1974 BOOL rc = FALSE;
1975 Win32BaseWindow *window;
1976 HWND hParent = 0;
1977
1978 dprintf (("SetWindowPos %x %x (%d,%d)(%d,%d) %x", Win32Hwnd, hwndInsertAfter, x, y, cx, cy, fuFlags));
1979
1980 if (fuFlags &
1981 ~(SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER |
1982 SWP_NOREDRAW | SWP_NOACTIVATE | SWP_FRAMECHANGED |
1983 SWP_SHOWWINDOW | SWP_HIDEWINDOW | SWP_NOCOPYBITS |
1984 SWP_NOOWNERZORDER))
1985 {
1986 return FALSE;
1987 }
1988
1989 WINDOWPOS wpos;
1990 SWP swp, swpOld;
1991
1992 wpos.flags = fuFlags;
1993 wpos.cy = cy;
1994 wpos.cx = cx;
1995 wpos.x = x;
1996 wpos.y = y;
1997 wpos.hwndInsertAfter = hwndInsertAfter;
1998 wpos.hwnd = getWindowHandle();
1999
2000 if(~fuFlags & (SWP_NOMOVE | SWP_NOSIZE)) {
2001 if (isChild())
2002 {
2003 hParent = getParent()->getOS2WindowHandle();
2004 OSLibWinQueryWindowPos(OS2Hwnd, &swpOld);
2005 }
2006 else
2007 OSLibWinQueryWindowPos(OS2HwndFrame, &swpOld);
2008 }
2009
2010 OSLibMapWINDOWPOStoSWP(&wpos, &swp, &swpOld, hParent, OS2HwndFrame);
2011 if (swp.fl == 0)
2012 return TRUE;
2013
2014 if ((swp.fl & SWPOS_ZORDER) && (swp.hwndInsertBehind > HWNDOS_BOTTOM))
2015 {
2016 Win32BaseWindow *wndBehind = Win32BaseWindow::GetWindowFromHandle(swp.hwndInsertBehind);
2017 swp.hwndInsertBehind = wndBehind->getOS2WindowHandle();
2018 }
2019 if (isFrameWindow())
2020 {
2021 POINT maxSize, maxPos, minTrack, maxTrack;
2022
2023 GetMinMaxInfo(&maxSize, &maxPos, &minTrack, &maxTrack);
2024
2025 if (swp.cx > maxTrack.x) swp.cx = maxTrack.x;
2026 if (swp.cy > maxTrack.y) swp.cy = maxTrack.y;
2027 if (swp.cx < minTrack.x) swp.cx = minTrack.x;
2028 if (swp.cy < minTrack.y) swp.cy = minTrack.y;
2029
2030 swp.hwnd = OS2HwndFrame;
2031 }
2032 else
2033 swp.hwnd = OS2Hwnd;
2034
2035 dprintf (("WinSetWindowPos %x %x (%d,%d)(%d,%d) %x", swp.hwnd, swp.hwndInsertBehind, swp.x, swp.y, swp.cx, swp.cy, swp.fl));
2036
2037 rc = OSLibWinSetMultWindowPos(&swp, 1);
2038
2039 if (rc == FALSE)
2040 {
2041 }
2042 else
2043 {
2044 if (fuFlags & SWP_FRAMECHANGED_W)
2045 OSLibSendMessage (OS2HwndFrame, 0x42 /*WM_UPDATEFRAME*/, -1, 0);
2046 }
2047
2048 return (rc);
2049}
2050//******************************************************************************
2051//Also destroys all the child windows (destroy parent, destroy children)
2052//******************************************************************************
2053BOOL Win32BaseWindow::DestroyWindow()
2054{
2055 return OSLibWinDestroyWindow(OS2HwndFrame);
2056}
2057//******************************************************************************
2058//******************************************************************************
2059HWND Win32BaseWindow::GetParent()
2060{
2061 if(getParent()) {
2062 return getParent()->getWindowHandle();
2063 }
2064 else return 0;
2065}
2066//******************************************************************************
2067//******************************************************************************
2068HWND Win32BaseWindow::SetParent(HWND hwndNewParent)
2069{
2070 HWND oldhwnd;
2071 Win32BaseWindow *newparent;
2072
2073 if(getParent()) {
2074 oldhwnd = getParent()->getWindowHandle();
2075 getParent()->RemoveChild(this);
2076 }
2077 else oldhwnd = 0;
2078
2079 if(hwndNewParent == 0) {//desktop window = parent
2080 setParent(NULL);
2081 OSLibWinSetParent(getOS2WindowHandle(), OSLIB_HWND_DESKTOP);
2082 return oldhwnd;
2083 }
2084 newparent = GetWindowFromHandle(hwndNewParent);
2085 if(newparent)
2086 {
2087 setParent(newparent);
2088 getParent()->AddChild(this);
2089 OSLibWinSetParent(getOS2WindowHandle(), getParent()->getOS2WindowHandle());
2090 return oldhwnd;
2091 }
2092 SetLastError(ERROR_INVALID_PARAMETER);
2093 return 0;
2094}
2095//******************************************************************************
2096//******************************************************************************
2097BOOL Win32BaseWindow::IsChild(HWND hwndParent)
2098{
2099 if(getParent()) {
2100 return getParent()->getWindowHandle() == hwndParent;
2101 }
2102 else return 0;
2103}
2104//******************************************************************************
2105//******************************************************************************
2106HWND Win32BaseWindow::GetTopWindow()
2107{
2108 return GetWindow(GW_CHILD);
2109}
2110//******************************************************************************
2111//Don't call WinUpdateWindow as that one also updates the child windows
2112//Also need to send WM_PAINT directly to the window procedure, which doesn't
2113//always happen with WinUpdateWindow (could be posted if thread doesn't own window)
2114//******************************************************************************
2115BOOL Win32BaseWindow::UpdateWindow()
2116{
2117 RECT rect;
2118
2119 if(OSLibWinQueryUpdateRect(OS2Hwnd, &rect))
2120 {//update region not empty
2121 HDC hdc;
2122
2123 hdc = O32_GetDC(OS2Hwnd);
2124 if (isIcon)
2125 {
2126 SendMessageA(WM_ICONERASEBKGND, (WPARAM)hdc, 0);
2127 SendMessageA(WM_PAINTICON, 0, 0);
2128 } else
2129 {
2130 SendMessageA(WM_ERASEBKGND, (WPARAM)hdc, 0);
2131 SendMessageA(WM_PAINT, 0, 0);
2132 }
2133 O32_ReleaseDC(OS2Hwnd, hdc);
2134 }
2135 return TRUE;
2136}
2137//******************************************************************************
2138//******************************************************************************
2139BOOL Win32BaseWindow::IsIconic()
2140{
2141 return OSLibWinIsIconic(OS2Hwnd);
2142}
2143//******************************************************************************
2144//TODO:
2145//We assume (for now) that if hwndParent or hwndChildAfter are real window handles, that
2146//the current process owns them.
2147//******************************************************************************
2148HWND Win32BaseWindow::FindWindowEx(HWND hwndParent, HWND hwndChildAfter, LPSTR lpszClass, LPSTR lpszWindow,
2149 BOOL fUnicode)
2150{
2151 Win32BaseWindow *parent = GetWindowFromHandle(hwndParent);
2152 Win32BaseWindow *child = GetWindowFromHandle(hwndChildAfter);
2153
2154 if((hwndParent != OSLIB_HWND_DESKTOP && !parent) ||
2155 (hwndChildAfter != 0 && !child) ||
2156 (hwndParent == OSLIB_HWND_DESKTOP && hwndChildAfter != 0))
2157 {
2158 dprintf(("Win32BaseWindow::FindWindowEx: parent or child not found %x %x", hwndParent, hwndChildAfter));
2159 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
2160 return 0;
2161 }
2162 if(hwndParent != OSLIB_HWND_DESKTOP)
2163 {//if the current process owns the window, just do a quick search
2164 child = (Win32BaseWindow *)parent->getFirstChild();
2165 if(hwndChildAfter != 0)
2166 {
2167 while(child)
2168 {
2169 if(child->getWindowHandle() == hwndChildAfter)
2170 {
2171 child = (Win32BaseWindow *)child->getNextChild();
2172 break;
2173 }
2174 child = (Win32BaseWindow *)child->getNextChild();
2175 }
2176 }
2177 while(child)
2178 {
2179 if(child->getWindowClass()->hasClassName(lpszClass, fUnicode) &&
2180 (!lpszWindow || child->hasWindowName(lpszWindow, fUnicode)))
2181 {
2182 dprintf(("FindWindowEx: Found window %x", child->getWindowHandle()));
2183 return child->getWindowHandle();
2184 }
2185 child = (Win32BaseWindow *)child->getNextChild();
2186 }
2187 }
2188 else {
2189 Win32BaseWindow *wnd;
2190 HWND henum, hwnd;
2191
2192 henum = OSLibWinBeginEnumWindows(OSLIB_HWND_DESKTOP);
2193 hwnd = OSLibWinGetNextWindow(henum);
2194
2195 while(hwnd)
2196 {
2197 wnd = GetWindowFromOS2Handle(hwnd);
2198 if(wnd == NULL) {
2199 hwnd = OSLibWinQueryClientWindow(hwnd);
2200 if(hwnd) wnd = GetWindowFromOS2Handle(hwnd);
2201 }
2202
2203 if(wnd) {
2204 LPVOID sharedmembase = (LPVOID)OSLibWinGetWindowULong(hwnd, OFFSET_WIN32PM_SHAREDMEM);
2205
2206 if(OSLibDosGetSharedMem(sharedmembase, MAX_HEAPSIZE, OSLIB_PAG_READ) != 0) {
2207 dprintf(("OSLibDosGetSharedMem returned error for %x", wnd));
2208 break;
2209 }
2210 if(wnd->getWindowClass()->hasClassName(lpszClass, fUnicode) &&
2211 (!lpszWindow || wnd->hasWindowName(lpszWindow, fUnicode)))
2212 {
2213 OSLibWinEndEnumWindows(henum);
2214 dprintf(("FindWindowEx: Found window %x", wnd->getWindowHandle()));
2215 return wnd->getWindowHandle();
2216 }
2217 }
2218 hwnd = OSLibWinGetNextWindow(henum);
2219 }
2220 OSLibWinEndEnumWindows(henum);
2221 }
2222 SetLastError(ERROR_CANNOT_FIND_WND_CLASS); //TODO: not always correct
2223 return 0;
2224}
2225//******************************************************************************
2226//TODO: not complete nor correct (distinction be tween top-level, top-most & child windows)
2227//******************************************************************************
2228HWND Win32BaseWindow::GetWindow(UINT uCmd)
2229{
2230 Win32BaseWindow *win32wnd;
2231 ULONG magic;
2232 ULONG getcmd = 0;
2233 HWND hwndRelated;
2234
2235 dprintf(("GetWindow %x %d NOT COMPLETE", getWindowHandle(), uCmd));
2236 switch(uCmd)
2237 {
2238 case GW_CHILD:
2239 getcmd = QWOS_TOP;
2240 break;
2241 case GW_HWNDFIRST:
2242 if(getParent()) {
2243 getcmd = QWOS_TOP; //top of child windows
2244 }
2245 else getcmd = QWOS_TOP; //TODO
2246 break;
2247 case GW_HWNDLAST:
2248 if(getParent()) {
2249 getcmd = QWOS_BOTTOM; //bottom of child windows
2250 }
2251 else getcmd = QWOS_BOTTOM; //TODO
2252 break;
2253 case GW_HWNDNEXT:
2254 getcmd = QWOS_NEXT;
2255 break;
2256 case GW_HWNDPREV:
2257 getcmd = QWOS_PREV;
2258 break;
2259 case GW_OWNER:
2260 if(owner) {
2261 return owner->getWindowHandle();
2262 }
2263 else return 0;
2264 }
2265 hwndRelated = OSLibWinQueryWindow(OS2Hwnd, getcmd);
2266 if(hwndRelated)
2267 {
2268 win32wnd = (Win32BaseWindow *)OSLibWinGetWindowULong(hwndRelated, OFFSET_WIN32WNDPTR);
2269 magic = OSLibWinGetWindowULong(hwndRelated, OFFSET_WIN32PM_MAGIC);
2270 if(CheckMagicDword(magic) && win32wnd)
2271 {
2272 return win32wnd->getWindowHandle();
2273 }
2274 }
2275 return 0;
2276}
2277//******************************************************************************
2278//******************************************************************************
2279HWND Win32BaseWindow::SetActiveWindow()
2280{
2281 return OSLibWinSetActiveWindow(OS2Hwnd);
2282}
2283//******************************************************************************
2284//WM_ENABLE is sent to hwnd, but not to it's children (as it should be)
2285//******************************************************************************
2286BOOL Win32BaseWindow::EnableWindow(BOOL fEnable)
2287{
2288 return OSLibWinEnableWindow(OS2Hwnd, fEnable);
2289}
2290//******************************************************************************
2291//******************************************************************************
2292BOOL Win32BaseWindow::CloseWindow()
2293{
2294 return OSLibWinMinimizeWindow(OS2Hwnd);
2295}
2296//******************************************************************************
2297//******************************************************************************
2298HWND Win32BaseWindow::GetActiveWindow()
2299{
2300 HWND hwndActive;
2301 Win32BaseWindow *win32wnd;
2302 ULONG magic;
2303
2304 hwndActive = OSLibWinQueryActiveWindow();
2305
2306 win32wnd = (Win32BaseWindow *)OSLibWinGetWindowULong(hwndActive, OFFSET_WIN32WNDPTR);
2307 magic = OSLibWinGetWindowULong(hwndActive, OFFSET_WIN32PM_MAGIC);
2308 if(CheckMagicDword(magic) && win32wnd)
2309 {
2310 return win32wnd->getWindowHandle();
2311 }
2312 return hwndActive;
2313}
2314//******************************************************************************
2315//******************************************************************************
2316BOOL Win32BaseWindow::IsWindowEnabled()
2317{
2318 return OSLibWinIsWindowEnabled(OS2Hwnd);
2319}
2320//******************************************************************************
2321//******************************************************************************
2322BOOL Win32BaseWindow::IsWindowVisible()
2323{
2324 return OSLibWinIsWindowVisible(OS2Hwnd);
2325}
2326//******************************************************************************
2327//******************************************************************************
2328BOOL Win32BaseWindow::GetWindowRect(PRECT pRect)
2329{
2330 return OSLibWinQueryWindowRect(OS2Hwnd, pRect, RELATIVE_TO_SCREEN);
2331}
2332//******************************************************************************
2333//******************************************************************************
2334BOOL Win32BaseWindow::hasWindowName(LPSTR wndname, BOOL fUnicode)
2335{
2336 if(fUnicode) {
2337 return (lstrcmpW(windowNameW, (LPWSTR)wndname) == 0);
2338 }
2339 else return (strcmp(windowNameA, wndname) == 0);
2340}
2341//******************************************************************************
2342//******************************************************************************
2343int Win32BaseWindow::GetWindowTextLength()
2344{
2345 return wndNameLength;
2346}
2347//******************************************************************************
2348//******************************************************************************
2349int Win32BaseWindow::GetWindowTextA(LPSTR lpsz, int cch)
2350{
2351 strncpy(lpsz, windowNameA, cch);
2352 return wndNameLength;
2353}
2354//******************************************************************************
2355//******************************************************************************
2356int Win32BaseWindow::GetWindowTextW(LPWSTR lpsz, int cch)
2357{
2358 lstrcpynW((LPWSTR)lpsz, windowNameW, cch);
2359 return wndNameLength;
2360}
2361//******************************************************************************
2362//******************************************************************************
2363BOOL Win32BaseWindow::SetWindowTextA(LPSTR lpsz)
2364{
2365 if(lpsz == NULL)
2366 return FALSE;
2367
2368 if(windowNameA) free(windowNameA);
2369 if(windowNameW) free(windowNameW);
2370
2371 windowNameA = (LPSTR)_smalloc(strlen(lpsz)+1);
2372 strcpy(windowNameA, lpsz);
2373 windowNameW = (LPWSTR)_smalloc((strlen(lpsz)+1)*sizeof(WCHAR));
2374 lstrcpyAtoW(windowNameW, windowNameA);
2375 wndNameLength = strlen(windowNameA)+1; //including 0 terminator
2376
2377 if(OS2HwndFrame)
2378 return OSLibWinSetWindowText(OS2HwndFrame, (LPSTR)windowNameA);
2379
2380 return TRUE;
2381}
2382//******************************************************************************
2383//******************************************************************************
2384BOOL Win32BaseWindow::SetWindowTextW(LPWSTR lpsz)
2385{
2386 if(lpsz == NULL)
2387 return FALSE;
2388
2389 if(windowNameA) free(windowNameA);
2390 if(windowNameW) free(windowNameW);
2391
2392 windowNameW = (LPWSTR)_smalloc((lstrlenW((LPWSTR)lpsz)+1)*sizeof(WCHAR));
2393 lstrcpyW(windowNameW, (LPWSTR)lpsz);
2394 windowNameA = (LPSTR)_smalloc(lstrlenW((LPWSTR)lpsz)+1);
2395 lstrcpyWtoA(windowNameA, windowNameW);
2396 wndNameLength = strlen(windowNameA)+1; //including 0 terminator
2397
2398 if(OS2HwndFrame)
2399 return OSLibWinSetWindowText(OS2HwndFrame, (LPSTR)windowNameA);
2400
2401 return TRUE;
2402}
2403//******************************************************************************
2404//******************************************************************************
2405LONG Win32BaseWindow::SetWindowLongA(int index, ULONG value)
2406{
2407 LONG oldval;
2408
2409 switch(index) {
2410 case GWL_EXSTYLE:
2411 {
2412 STYLESTRUCT ss;
2413
2414 ss.styleOld = dwExStyle;
2415 ss.styleNew = value;
2416 SendMessageA(WM_STYLECHANGING,GWL_EXSTYLE,(LPARAM)&ss);
2417 setExStyle(ss.styleNew);
2418 SendMessageA(WM_STYLECHANGED,GWL_EXSTYLE,(LPARAM)&ss);
2419 return ss.styleOld;
2420 }
2421 case GWL_STYLE:
2422 {
2423 STYLESTRUCT ss;
2424
2425 ss.styleOld = dwStyle;
2426 ss.styleNew = value;
2427 SendMessageA(WM_STYLECHANGING,GWL_STYLE,(LPARAM)&ss);
2428 setStyle(ss.styleNew);
2429 OSLibSetWindowStyle(OS2HwndFrame, dwStyle);
2430 SendMessageA(WM_STYLECHANGED,GWL_STYLE,(LPARAM)&ss);
2431 return ss.styleOld;
2432 }
2433 case GWL_WNDPROC:
2434 oldval = (LONG)getWindowProc();
2435 setWindowProc((WNDPROC)value);
2436 return oldval;
2437 case GWL_HINSTANCE:
2438 oldval = hInstance;
2439 hInstance = value;
2440 return oldval;
2441 case GWL_HWNDPARENT:
2442 return SetParent((HWND)value);
2443 case GWL_ID:
2444 oldval = getWindowId();
2445 setWindowId(value);
2446 return oldval;
2447 case GWL_USERDATA:
2448 oldval = userData;
2449 userData = value;
2450 return oldval;
2451 default:
2452 if(index >= 0 && index/4 < nrUserWindowLong)
2453 {
2454 oldval = userWindowLong[index/4];
2455 userWindowLong[index/4] = value;
2456 return oldval;
2457 }
2458 SetLastError(ERROR_INVALID_PARAMETER);
2459 return 0;
2460 }
2461}
2462//******************************************************************************
2463//******************************************************************************
2464ULONG Win32BaseWindow::GetWindowLongA(int index)
2465{
2466 switch(index) {
2467 case GWL_EXSTYLE:
2468 return dwExStyle;
2469 case GWL_STYLE:
2470 return dwStyle;
2471 case GWL_WNDPROC:
2472 return (ULONG)getWindowProc();
2473 case GWL_HINSTANCE:
2474 return hInstance;
2475 case GWL_HWNDPARENT:
2476 if(getParent()) {
2477 return getParent()->getWindowHandle();
2478 }
2479 else return 0;
2480 case GWL_ID:
2481 return getWindowId();
2482 case GWL_USERDATA:
2483 return userData;
2484 default:
2485 if(index >= 0 && index/4 < nrUserWindowLong)
2486 {
2487 return userWindowLong[index/4];
2488 }
2489 SetLastError(ERROR_INVALID_PARAMETER);
2490 return 0;
2491 }
2492}
2493//******************************************************************************
2494//******************************************************************************
2495WORD Win32BaseWindow::SetWindowWord(int index, WORD value)
2496{
2497 WORD oldval;
2498
2499 if(index >= 0 && index/4 < nrUserWindowLong)
2500 {
2501 oldval = ((WORD *)userWindowLong)[index/2];
2502 ((WORD *)userWindowLong)[index/2] = value;
2503 return oldval;
2504 }
2505 SetLastError(ERROR_INVALID_PARAMETER);
2506 return 0;
2507}
2508//******************************************************************************
2509//******************************************************************************
2510WORD Win32BaseWindow::GetWindowWord(int index)
2511{
2512 if(index >= 0 && index/4 < nrUserWindowLong)
2513 {
2514 return ((WORD *)userWindowLong)[index/2];
2515 }
2516 SetLastError(ERROR_INVALID_PARAMETER);
2517 return 0;
2518}
2519//******************************************************************************
2520//******************************************************************************
2521void Win32BaseWindow::setWindowId(DWORD id)
2522{
2523 windowId = id;
2524 OSLibSetWindowID(OS2HwndFrame, id);
2525}
2526//******************************************************************************
2527//******************************************************************************
2528Win32BaseWindow *Win32BaseWindow::GetWindowFromHandle(HWND hwnd)
2529{
2530 Win32BaseWindow *window;
2531
2532 if(HwGetWindowHandleData(hwnd, (DWORD *)&window) == TRUE) {
2533 return window;
2534 }
2535 else return NULL;
2536}
2537//******************************************************************************
2538//******************************************************************************
2539Win32BaseWindow *Win32BaseWindow::GetWindowFromOS2Handle(HWND hwnd)
2540{
2541 Win32BaseWindow *win32wnd;
2542 DWORD magic;
2543
2544 win32wnd = (Win32BaseWindow *)OSLibWinGetWindowULong(hwnd, OFFSET_WIN32WNDPTR);
2545 magic = OSLibWinGetWindowULong(hwnd, OFFSET_WIN32PM_MAGIC);
2546
2547 if(win32wnd && CheckMagicDword(magic)) {
2548 return win32wnd;
2549 }
2550 return 0;
2551}
2552//******************************************************************************
2553//******************************************************************************
2554Win32BaseWindow *Win32BaseWindow::GetWindowFromOS2FrameHandle(HWND hwnd)
2555{
2556 Win32BaseWindow *win32wnd;
2557 DWORD magic;
2558
2559 return GetWindowFromOS2Handle(OSLibWinWindowFromID(hwnd,OSLIB_FID_CLIENT));
2560
2561 //CB: doesn't work with frame window words
2562/*
2563 win32wnd = (Win32BaseWindow *)OSLibWinGetWindowULong(hwnd, OFFSET_WIN32WNDPTR);
2564 magic = OSLibWinGetWindowULong(hwnd, OFFSET_WIN32PM_MAGIC);
2565
2566 if(win32wnd && CheckMagicDword(magic)) {
2567 return win32wnd;
2568 }
2569 return 0;
2570*/
2571}
2572//******************************************************************************
2573//******************************************************************************
2574HWND Win32BaseWindow::Win32ToOS2Handle(HWND hwnd)
2575{
2576 Win32BaseWindow *window = GetWindowFromHandle(hwnd);
2577
2578 if(window) {
2579 return window->getOS2WindowHandle();
2580 }
2581 else return hwnd; //OS/2 window handle
2582}
2583//******************************************************************************
2584//******************************************************************************
2585HWND Win32BaseWindow::OS2ToWin32Handle(HWND hwnd)
2586{
2587 Win32BaseWindow *window = GetWindowFromOS2Handle(hwnd);
2588
2589 if(window) {
2590 return window->getWindowHandle();
2591 }
2592 else return hwnd; //OS/2 window handle
2593}
2594//******************************************************************************
2595//******************************************************************************
2596GenericObject *Win32BaseWindow::windows = NULL;
Note: See TracBrowser for help on using the repository browser.