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

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

Lots of window fixes & changes

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