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

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

GetWindow + EB's message bugfixes

File size: 92.3 KB
Line 
1/* $Id: win32wbase.cpp,v 1.44 1999-10-15 10:03:15 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#if 0
1966 if(showstate & SWPOS_SHOW && (getStyle() & WS_VISIBLE) == 0) {
1967 SetWindowLongA(GWL_STYLE, getStyle() | WS_VISIBLE);
1968 }
1969#endif
1970 BOOL rc = OSLibWinShowWindow(OS2HwndFrame, showstate);
1971 return rc;
1972}
1973//******************************************************************************
1974//******************************************************************************
1975BOOL Win32BaseWindow::SetWindowPos(HWND hwndInsertAfter, int x, int y, int cx, int cy, UINT fuFlags)
1976{
1977 BOOL rc = FALSE;
1978 Win32BaseWindow *window;
1979 HWND hParent = 0;
1980
1981 dprintf (("SetWindowPos %x %x (%d,%d)(%d,%d) %x", Win32Hwnd, hwndInsertAfter, x, y, cx, cy, fuFlags));
1982
1983 if (fuFlags &
1984 ~(SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER |
1985 SWP_NOREDRAW | SWP_NOACTIVATE | SWP_FRAMECHANGED |
1986 SWP_SHOWWINDOW | SWP_HIDEWINDOW | SWP_NOCOPYBITS |
1987 SWP_NOOWNERZORDER))
1988 {
1989 return FALSE;
1990 }
1991
1992 WINDOWPOS wpos;
1993 SWP swp, swpOld;
1994
1995 wpos.flags = fuFlags;
1996 wpos.cy = cy;
1997 wpos.cx = cx;
1998 wpos.x = x;
1999 wpos.y = y;
2000 wpos.hwndInsertAfter = hwndInsertAfter;
2001 wpos.hwnd = getWindowHandle();
2002
2003 if(~fuFlags & (SWP_NOMOVE | SWP_NOSIZE))
2004 {
2005 if (isChild())
2006 {
2007 hParent = getParent()->getOS2WindowHandle();
2008 }
2009 OSLibWinQueryWindowPos(OS2HwndFrame, &swpOld);
2010 }
2011
2012 OSLibMapWINDOWPOStoSWP(&wpos, &swp, &swpOld, hParent, OS2HwndFrame);
2013 if (swp.fl == 0)
2014 return TRUE;
2015
2016// if ((swp.fl & SWPOS_ZORDER) && (swp.hwndInsertBehind > HWNDOS_BOTTOM))
2017 if ((swp.hwndInsertBehind > HWNDOS_BOTTOM))
2018 {
2019 Win32BaseWindow *wndBehind = Win32BaseWindow::GetWindowFromHandle(swp.hwndInsertBehind);
2020 if(wndBehind) {
2021 swp.hwndInsertBehind = wndBehind->getOS2WindowHandle();
2022 }
2023 else {
2024 dprintf(("ERROR: SetWindowPos: hwndInsertBehind %x invalid!",swp.hwndInsertBehind));
2025 swp.hwndInsertBehind = 0;
2026 }
2027 }
2028#if 0
2029 if (isFrameWindow())
2030 {
2031 if (!isChild())
2032 {
2033 POINT maxSize, maxPos, minTrack, maxTrack;
2034
2035 GetMinMaxInfo(&maxSize, &maxPos, &minTrack, &maxTrack);
2036
2037 if (swp.cx > maxTrack.x) swp.cx = maxTrack.x;
2038 if (swp.cy > maxTrack.y) swp.cy = maxTrack.y;
2039 if (swp.cx < minTrack.x) swp.cx = minTrack.x;
2040 if (swp.cy < minTrack.y) swp.cy = minTrack.y;
2041 }
2042 swp.hwnd = OS2HwndFrame;
2043 }
2044 else
2045#endif
2046 swp.hwnd = OS2HwndFrame;
2047
2048 dprintf (("WinSetWindowPos %x %x (%d,%d)(%d,%d) %x", swp.hwnd, swp.hwndInsertBehind, swp.x, swp.y, swp.cx, swp.cy, swp.fl));
2049
2050 rc = OSLibWinSetMultWindowPos(&swp, 1);
2051
2052 if (rc == FALSE)
2053 {
2054 dprintf(("OSLibWinSetMultWindowPos failed!"));
2055 }
2056 else
2057 {
2058 if (fuFlags & SWP_FRAMECHANGED_W)
2059 OSLibSendMessage (OS2HwndFrame, 0x42 /*WM_UPDATEFRAME*/, -1, 0);
2060 }
2061
2062 return (rc);
2063}
2064//******************************************************************************
2065//Also destroys all the child windows (destroy parent, destroy children)
2066//******************************************************************************
2067BOOL Win32BaseWindow::DestroyWindow()
2068{
2069 return OSLibWinDestroyWindow(OS2HwndFrame);
2070}
2071//******************************************************************************
2072//******************************************************************************
2073HWND Win32BaseWindow::GetParent()
2074{
2075 if(getParent()) {
2076 return getParent()->getWindowHandle();
2077 }
2078 else return 0;
2079}
2080//******************************************************************************
2081//******************************************************************************
2082HWND Win32BaseWindow::SetParent(HWND hwndNewParent)
2083{
2084 HWND oldhwnd;
2085 Win32BaseWindow *newparent;
2086
2087 if(getParent()) {
2088 oldhwnd = getParent()->getWindowHandle();
2089 getParent()->RemoveChild(this);
2090 }
2091 else oldhwnd = 0;
2092
2093 if(hwndNewParent == 0) {//desktop window = parent
2094 setParent(NULL);
2095 OSLibWinSetParent(getOS2WindowHandle(), OSLIB_HWND_DESKTOP);
2096 return oldhwnd;
2097 }
2098 newparent = GetWindowFromHandle(hwndNewParent);
2099 if(newparent)
2100 {
2101 setParent(newparent);
2102 getParent()->AddChild(this);
2103 OSLibWinSetParent(getOS2WindowHandle(), getParent()->getOS2WindowHandle());
2104 return oldhwnd;
2105 }
2106 SetLastError(ERROR_INVALID_PARAMETER);
2107 return 0;
2108}
2109//******************************************************************************
2110//******************************************************************************
2111BOOL Win32BaseWindow::IsChild(HWND hwndParent)
2112{
2113 if(getParent()) {
2114 return getParent()->getWindowHandle() == hwndParent;
2115 }
2116 else return 0;
2117}
2118//******************************************************************************
2119//******************************************************************************
2120HWND Win32BaseWindow::GetTopWindow()
2121{
2122 return GetWindow(GW_CHILD);
2123}
2124//******************************************************************************
2125// Get the top-level parent for a child window.
2126//******************************************************************************
2127Win32BaseWindow *Win32BaseWindow::GetTopParent()
2128{
2129 Win32BaseWindow *window = this;
2130
2131 while(window && (window->getStyle() & WS_CHILD))
2132 {
2133 window = window->getParent();
2134 }
2135 return window;
2136}
2137//******************************************************************************
2138//Don't call WinUpdateWindow as that one also updates the child windows
2139//Also need to send WM_PAINT directly to the window procedure, which doesn't
2140//always happen with WinUpdateWindow (could be posted if thread doesn't own window)
2141//******************************************************************************
2142BOOL Win32BaseWindow::UpdateWindow()
2143{
2144 RECT rect;
2145
2146 if(OSLibWinQueryUpdateRect(OS2Hwnd, &rect))
2147 {//update region not empty
2148 HDC hdc;
2149
2150 hdc = O32_GetDC(OS2Hwnd);
2151 if (isIcon)
2152 {
2153 SendMessageA(WM_ICONERASEBKGND, (WPARAM)hdc, 0);
2154 SendMessageA(WM_PAINTICON, 0, 0);
2155 } else
2156 {
2157 SendMessageA(WM_ERASEBKGND, (WPARAM)hdc, 0);
2158 SendMessageA(WM_PAINT, 0, 0);
2159 }
2160 O32_ReleaseDC(OS2Hwnd, hdc);
2161 }
2162 return TRUE;
2163}
2164//******************************************************************************
2165//******************************************************************************
2166BOOL Win32BaseWindow::IsIconic()
2167{
2168 return OSLibWinIsIconic(OS2Hwnd);
2169}
2170//******************************************************************************
2171//TODO:
2172//We assume (for now) that if hwndParent or hwndChildAfter are real window handles, that
2173//the current process owns them.
2174//******************************************************************************
2175HWND Win32BaseWindow::FindWindowEx(HWND hwndParent, HWND hwndChildAfter, LPSTR lpszClass, LPSTR lpszWindow,
2176 BOOL fUnicode)
2177{
2178 Win32BaseWindow *parent = GetWindowFromHandle(hwndParent);
2179 Win32BaseWindow *child = GetWindowFromHandle(hwndChildAfter);
2180
2181 if((hwndParent != OSLIB_HWND_DESKTOP && !parent) ||
2182 (hwndChildAfter != 0 && !child) ||
2183 (hwndParent == OSLIB_HWND_DESKTOP && hwndChildAfter != 0))
2184 {
2185 dprintf(("Win32BaseWindow::FindWindowEx: parent or child not found %x %x", hwndParent, hwndChildAfter));
2186 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
2187 return 0;
2188 }
2189 if(hwndParent != OSLIB_HWND_DESKTOP)
2190 {//if the current process owns the window, just do a quick search
2191 child = (Win32BaseWindow *)parent->getFirstChild();
2192 if(hwndChildAfter != 0)
2193 {
2194 while(child)
2195 {
2196 if(child->getWindowHandle() == hwndChildAfter)
2197 {
2198 child = (Win32BaseWindow *)child->getNextChild();
2199 break;
2200 }
2201 child = (Win32BaseWindow *)child->getNextChild();
2202 }
2203 }
2204 while(child)
2205 {
2206 if(child->getWindowClass()->hasClassName(lpszClass, fUnicode) &&
2207 (!lpszWindow || child->hasWindowName(lpszWindow, fUnicode)))
2208 {
2209 dprintf(("FindWindowEx: Found window %x", child->getWindowHandle()));
2210 return child->getWindowHandle();
2211 }
2212 child = (Win32BaseWindow *)child->getNextChild();
2213 }
2214 }
2215 else {
2216 Win32BaseWindow *wnd;
2217 HWND henum, hwnd;
2218
2219 henum = OSLibWinBeginEnumWindows(OSLIB_HWND_DESKTOP);
2220 hwnd = OSLibWinGetNextWindow(henum);
2221
2222 while(hwnd)
2223 {
2224 wnd = GetWindowFromOS2Handle(hwnd);
2225 if(wnd == NULL) {
2226 hwnd = OSLibWinQueryClientWindow(hwnd);
2227 if(hwnd) wnd = GetWindowFromOS2Handle(hwnd);
2228 }
2229
2230 if(wnd) {
2231 LPVOID sharedmembase = (LPVOID)OSLibWinGetWindowULong(hwnd, OFFSET_WIN32PM_SHAREDMEM);
2232
2233 if(OSLibDosGetSharedMem(sharedmembase, MAX_HEAPSIZE, OSLIB_PAG_READ) != 0) {
2234 dprintf(("OSLibDosGetSharedMem returned error for %x", wnd));
2235 break;
2236 }
2237 if(wnd->getWindowClass()->hasClassName(lpszClass, fUnicode) &&
2238 (!lpszWindow || wnd->hasWindowName(lpszWindow, fUnicode)))
2239 {
2240 OSLibWinEndEnumWindows(henum);
2241 dprintf(("FindWindowEx: Found window %x", wnd->getWindowHandle()));
2242 return wnd->getWindowHandle();
2243 }
2244 }
2245 hwnd = OSLibWinGetNextWindow(henum);
2246 }
2247 OSLibWinEndEnumWindows(henum);
2248 }
2249 SetLastError(ERROR_CANNOT_FIND_WND_CLASS); //TODO: not always correct
2250 return 0;
2251}
2252//******************************************************************************
2253//TODO: not complete nor correct (distinction be tween top-level, top-most & child windows)
2254//******************************************************************************
2255HWND Win32BaseWindow::GetWindow(UINT uCmd)
2256{
2257 Win32BaseWindow *win32wnd;
2258 ULONG magic;
2259 ULONG getcmd = 0;
2260 HWND hwndRelated, hwnd;
2261
2262 dprintf(("GetWindow %x %d NOT COMPLETE", getWindowHandle(), uCmd));
2263 hwnd = OS2Hwnd;
2264 switch(uCmd)
2265 {
2266 case GW_CHILD:
2267 getcmd = QWOS_TOP;
2268 break;
2269 case GW_HWNDFIRST:
2270 if(getParent()) {
2271 hwnd = getParent()->getOS2WindowHandle();
2272 getcmd = QWOS_TOP; //top of child windows
2273 }
2274 else getcmd = QWOS_TOP; //TODO
2275 break;
2276 case GW_HWNDLAST:
2277 if(getParent()) {
2278 hwnd = getParent()->getOS2WindowHandle();
2279 getcmd = QWOS_BOTTOM; //bottom of child windows
2280 }
2281 else getcmd = QWOS_BOTTOM; //TODO
2282 break;
2283 case GW_HWNDNEXT:
2284 getcmd = QWOS_NEXT;
2285 break;
2286 case GW_HWNDPREV:
2287 getcmd = QWOS_PREV;
2288 break;
2289 case GW_OWNER:
2290 if(owner) {
2291 return owner->getWindowHandle();
2292 }
2293 else return 0;
2294 }
2295 hwndRelated = OSLibWinQueryWindow(hwnd, getcmd);
2296 if(hwndRelated)
2297 {
2298 win32wnd = (Win32BaseWindow *)OSLibWinGetWindowULong(hwndRelated, OFFSET_WIN32WNDPTR);
2299 magic = OSLibWinGetWindowULong(hwndRelated, OFFSET_WIN32PM_MAGIC);
2300 if(CheckMagicDword(magic) && win32wnd)
2301 {
2302 return win32wnd->getWindowHandle();
2303 }
2304
2305 hwndRelated = OSLibWinWindowFromID(hwndRelated, OSLIB_FID_CLIENT);
2306 win32wnd = (Win32BaseWindow *)OSLibWinGetWindowULong(hwndRelated, OFFSET_WIN32WNDPTR);
2307 magic = OSLibWinGetWindowULong(hwndRelated, OFFSET_WIN32PM_MAGIC);
2308 if(CheckMagicDword(magic) && win32wnd)
2309 {
2310 return win32wnd->getWindowHandle();
2311 }
2312 }
2313 return 0;
2314}
2315//******************************************************************************
2316//******************************************************************************
2317HWND Win32BaseWindow::SetActiveWindow()
2318{
2319 return OSLibWinSetActiveWindow(OS2Hwnd);
2320}
2321//******************************************************************************
2322//WM_ENABLE is sent to hwnd, but not to it's children (as it should be)
2323//******************************************************************************
2324BOOL Win32BaseWindow::EnableWindow(BOOL fEnable)
2325{
2326 return OSLibWinEnableWindow(OS2Hwnd, fEnable);
2327}
2328//******************************************************************************
2329//******************************************************************************
2330BOOL Win32BaseWindow::CloseWindow()
2331{
2332 return OSLibWinMinimizeWindow(OS2Hwnd);
2333}
2334//******************************************************************************
2335//******************************************************************************
2336HWND Win32BaseWindow::GetActiveWindow()
2337{
2338 HWND hwndActive;
2339 Win32BaseWindow *win32wnd;
2340 ULONG magic;
2341
2342 hwndActive = OSLibWinQueryActiveWindow();
2343
2344 win32wnd = (Win32BaseWindow *)OSLibWinGetWindowULong(hwndActive, OFFSET_WIN32WNDPTR);
2345 magic = OSLibWinGetWindowULong(hwndActive, OFFSET_WIN32PM_MAGIC);
2346 if(CheckMagicDword(magic) && win32wnd)
2347 {
2348 return win32wnd->getWindowHandle();
2349 }
2350 return hwndActive;
2351}
2352//******************************************************************************
2353//******************************************************************************
2354BOOL Win32BaseWindow::IsWindowEnabled()
2355{
2356 return OSLibWinIsWindowEnabled(OS2Hwnd);
2357}
2358//******************************************************************************
2359//******************************************************************************
2360BOOL Win32BaseWindow::IsWindowVisible()
2361{
2362 return OSLibWinIsWindowVisible(OS2Hwnd);
2363}
2364//******************************************************************************
2365//******************************************************************************
2366BOOL Win32BaseWindow::GetWindowRect(PRECT pRect)
2367{
2368 return OSLibWinQueryWindowRect(OS2HwndFrame, pRect, RELATIVE_TO_SCREEN);
2369}
2370//******************************************************************************
2371//******************************************************************************
2372BOOL Win32BaseWindow::hasWindowName(LPSTR wndname, BOOL fUnicode)
2373{
2374 if(fUnicode) {
2375 return (lstrcmpW(windowNameW, (LPWSTR)wndname) == 0);
2376 }
2377 else return (strcmp(windowNameA, wndname) == 0);
2378}
2379//******************************************************************************
2380//******************************************************************************
2381int Win32BaseWindow::GetWindowTextLength()
2382{
2383 return wndNameLength;
2384}
2385//******************************************************************************
2386//******************************************************************************
2387int Win32BaseWindow::GetWindowTextA(LPSTR lpsz, int cch)
2388{
2389 strncpy(lpsz, windowNameA, cch);
2390 return wndNameLength;
2391}
2392//******************************************************************************
2393//******************************************************************************
2394int Win32BaseWindow::GetWindowTextW(LPWSTR lpsz, int cch)
2395{
2396 lstrcpynW((LPWSTR)lpsz, windowNameW, cch);
2397 return wndNameLength;
2398}
2399//******************************************************************************
2400//******************************************************************************
2401BOOL Win32BaseWindow::SetWindowTextA(LPSTR lpsz)
2402{
2403 if(lpsz == NULL)
2404 return FALSE;
2405
2406 if(windowNameA) free(windowNameA);
2407 if(windowNameW) free(windowNameW);
2408
2409 windowNameA = (LPSTR)_smalloc(strlen(lpsz)+1);
2410 strcpy(windowNameA, lpsz);
2411 windowNameW = (LPWSTR)_smalloc((strlen(lpsz)+1)*sizeof(WCHAR));
2412 lstrcpyAtoW(windowNameW, windowNameA);
2413 wndNameLength = strlen(windowNameA)+1; //including 0 terminator
2414
2415 if(OS2HwndFrame)
2416 return OSLibWinSetWindowText(OS2HwndFrame, (LPSTR)windowNameA);
2417
2418 return TRUE;
2419}
2420//******************************************************************************
2421//******************************************************************************
2422BOOL Win32BaseWindow::SetWindowTextW(LPWSTR lpsz)
2423{
2424 if(lpsz == NULL)
2425 return FALSE;
2426
2427 if(windowNameA) free(windowNameA);
2428 if(windowNameW) free(windowNameW);
2429
2430 windowNameW = (LPWSTR)_smalloc((lstrlenW((LPWSTR)lpsz)+1)*sizeof(WCHAR));
2431 lstrcpyW(windowNameW, (LPWSTR)lpsz);
2432 windowNameA = (LPSTR)_smalloc(lstrlenW((LPWSTR)lpsz)+1);
2433 lstrcpyWtoA(windowNameA, windowNameW);
2434 wndNameLength = strlen(windowNameA)+1; //including 0 terminator
2435
2436 if(OS2HwndFrame)
2437 return OSLibWinSetWindowText(OS2HwndFrame, (LPSTR)windowNameA);
2438
2439 return TRUE;
2440}
2441//******************************************************************************
2442//******************************************************************************
2443LONG Win32BaseWindow::SetWindowLongA(int index, ULONG value)
2444{
2445 LONG oldval;
2446
2447 switch(index) {
2448 case GWL_EXSTYLE:
2449 {
2450 STYLESTRUCT ss;
2451
2452 ss.styleOld = dwExStyle;
2453 ss.styleNew = value;
2454 SendMessageA(WM_STYLECHANGING,GWL_EXSTYLE,(LPARAM)&ss);
2455 setExStyle(ss.styleNew);
2456 SendMessageA(WM_STYLECHANGED,GWL_EXSTYLE,(LPARAM)&ss);
2457 return ss.styleOld;
2458 }
2459 case GWL_STYLE:
2460 {
2461 STYLESTRUCT ss;
2462
2463 ss.styleOld = dwStyle;
2464 ss.styleNew = value;
2465 SendMessageA(WM_STYLECHANGING,GWL_STYLE,(LPARAM)&ss);
2466 setStyle(ss.styleNew);
2467 OSLibSetWindowStyle(OS2HwndFrame, dwStyle);
2468 SendMessageA(WM_STYLECHANGED,GWL_STYLE,(LPARAM)&ss);
2469 return ss.styleOld;
2470 }
2471 case GWL_WNDPROC:
2472 oldval = (LONG)getWindowProc();
2473 setWindowProc((WNDPROC)value);
2474 return oldval;
2475 case GWL_HINSTANCE:
2476 oldval = hInstance;
2477 hInstance = value;
2478 return oldval;
2479 case GWL_HWNDPARENT:
2480 return SetParent((HWND)value);
2481 case GWL_ID:
2482 oldval = getWindowId();
2483 setWindowId(value);
2484 return oldval;
2485 case GWL_USERDATA:
2486 oldval = userData;
2487 userData = value;
2488 return oldval;
2489 default:
2490 if(index >= 0 && index/4 < nrUserWindowLong)
2491 {
2492 oldval = userWindowLong[index/4];
2493 userWindowLong[index/4] = value;
2494 return oldval;
2495 }
2496 SetLastError(ERROR_INVALID_PARAMETER);
2497 return 0;
2498 }
2499}
2500//******************************************************************************
2501//******************************************************************************
2502ULONG Win32BaseWindow::GetWindowLongA(int index)
2503{
2504 switch(index) {
2505 case GWL_EXSTYLE:
2506 return dwExStyle;
2507 case GWL_STYLE:
2508 return dwStyle;
2509 case GWL_WNDPROC:
2510 return (ULONG)getWindowProc();
2511 case GWL_HINSTANCE:
2512 return hInstance;
2513 case GWL_HWNDPARENT:
2514 if(getParent()) {
2515 return getParent()->getWindowHandle();
2516 }
2517 else return 0;
2518 case GWL_ID:
2519 return getWindowId();
2520 case GWL_USERDATA:
2521 return userData;
2522 default:
2523 if(index >= 0 && index/4 < nrUserWindowLong)
2524 {
2525 return userWindowLong[index/4];
2526 }
2527 SetLastError(ERROR_INVALID_PARAMETER);
2528 return 0;
2529 }
2530}
2531//******************************************************************************
2532//******************************************************************************
2533WORD Win32BaseWindow::SetWindowWord(int index, WORD value)
2534{
2535 WORD oldval;
2536
2537 if(index >= 0 && index/4 < nrUserWindowLong)
2538 {
2539 oldval = ((WORD *)userWindowLong)[index/2];
2540 ((WORD *)userWindowLong)[index/2] = value;
2541 return oldval;
2542 }
2543 SetLastError(ERROR_INVALID_PARAMETER);
2544 return 0;
2545}
2546//******************************************************************************
2547//******************************************************************************
2548WORD Win32BaseWindow::GetWindowWord(int index)
2549{
2550 if(index >= 0 && index/4 < nrUserWindowLong)
2551 {
2552 return ((WORD *)userWindowLong)[index/2];
2553 }
2554 SetLastError(ERROR_INVALID_PARAMETER);
2555 return 0;
2556}
2557//******************************************************************************
2558//******************************************************************************
2559void Win32BaseWindow::setWindowId(DWORD id)
2560{
2561 windowId = id;
2562 OSLibSetWindowID(OS2HwndFrame, id);
2563}
2564//******************************************************************************
2565//******************************************************************************
2566Win32BaseWindow *Win32BaseWindow::GetWindowFromHandle(HWND hwnd)
2567{
2568 Win32BaseWindow *window;
2569
2570 if(hwnd == NULL && windowDesktop)
2571 return windowDesktop;
2572
2573 if(HwGetWindowHandleData(hwnd, (DWORD *)&window) == TRUE) {
2574 return window;
2575 }
2576 else return NULL;
2577}
2578//******************************************************************************
2579//******************************************************************************
2580Win32BaseWindow *Win32BaseWindow::GetWindowFromOS2Handle(HWND hwnd)
2581{
2582 Win32BaseWindow *win32wnd;
2583 DWORD magic;
2584
2585 win32wnd = (Win32BaseWindow *)OSLibWinGetWindowULong(hwnd, OFFSET_WIN32WNDPTR);
2586 magic = OSLibWinGetWindowULong(hwnd, OFFSET_WIN32PM_MAGIC);
2587
2588 if(win32wnd && CheckMagicDword(magic)) {
2589 return win32wnd;
2590 }
2591 return 0;
2592}
2593//******************************************************************************
2594//******************************************************************************
2595Win32BaseWindow *Win32BaseWindow::GetWindowFromOS2FrameHandle(HWND hwnd)
2596{
2597 return GetWindowFromOS2Handle(OSLibWinWindowFromID(hwnd,OSLIB_FID_CLIENT));
2598}
2599//******************************************************************************
2600//******************************************************************************
2601HWND Win32BaseWindow::Win32ToOS2Handle(HWND hwnd)
2602{
2603 Win32BaseWindow *window = GetWindowFromHandle(hwnd);
2604
2605 if(window) {
2606 return window->getOS2WindowHandle();
2607 }
2608 else return hwnd;
2609}
2610//******************************************************************************
2611//******************************************************************************
2612HWND Win32BaseWindow::Win32ToOS2FrameHandle(HWND hwnd)
2613{
2614 Win32BaseWindow *window = GetWindowFromHandle(hwnd);
2615
2616 if(window) {
2617 return window->getOS2FrameWindowHandle();
2618 }
2619 else return hwnd;
2620}
2621//******************************************************************************
2622//******************************************************************************
2623HWND Win32BaseWindow::OS2ToWin32Handle(HWND hwnd)
2624{
2625 Win32BaseWindow *window = GetWindowFromOS2Handle(hwnd);
2626
2627 if(window) {
2628 return window->getWindowHandle();
2629 }
2630 window = GetWindowFromOS2FrameHandle(hwnd);
2631 if(window) {
2632 return window->getWindowHandle();
2633 }
2634 else return hwnd; //OS/2 window handle
2635}
2636//******************************************************************************
2637//******************************************************************************
2638#ifdef DEBUG
2639void PrintWindowStyle(DWORD dwStyle, DWORD dwExStyle)
2640{
2641 char style[256] = "";
2642 char exstyle[256] = "";
2643
2644 /* Window styles */
2645 if(dwStyle & WS_CHILD)
2646 strcat(style, "WS_CHILD ");
2647 if(dwStyle & WS_POPUP)
2648 strcat(style, "WS_POPUP ");
2649 if(dwStyle & WS_VISIBLE)
2650 strcat(style, "WS_VISIBLE ");
2651 if(dwStyle & WS_DISABLED)
2652 strcat(style, "WS_DISABLED ");
2653 if(dwStyle & WS_CLIPSIBLINGS)
2654 strcat(style, "WS_CLIPSIBLINGS ");
2655 if(dwStyle & WS_CLIPCHILDREN)
2656 strcat(style, "WS_CLIPCHILDREN ");
2657 if(dwStyle & WS_MAXIMIZE)
2658 strcat(style, "WS_MAXIMIZE ");
2659 if(dwStyle & WS_MINIMIZE)
2660 strcat(style, "WS_MINIMIZE ");
2661 if(dwStyle & WS_GROUP)
2662 strcat(style, "WS_GROUP ");
2663 if(dwStyle & WS_TABSTOP)
2664 strcat(style, "WS_TABSTOP ");
2665
2666 if((dwStyle & WS_CAPTION) == WS_CAPTION)
2667 strcat(style, "WS_CAPTION ");
2668 if(dwStyle & WS_DLGFRAME)
2669 strcat(style, "WS_DLGFRAME ");
2670 if(dwStyle & WS_BORDER)
2671 strcat(style, "WS_BORDER ");
2672
2673 if(dwStyle & WS_VSCROLL)
2674 strcat(style, "WS_VSCROLL ");
2675 if(dwStyle & WS_HSCROLL)
2676 strcat(style, "WS_HSCROLL ");
2677 if(dwStyle & WS_SYSMENU)
2678 strcat(style, "WS_SYSMENU ");
2679 if(dwStyle & WS_THICKFRAME)
2680 strcat(style, "WS_THICKFRAME ");
2681 if(dwStyle & WS_MINIMIZEBOX)
2682 strcat(style, "WS_MINIMIZEBOX ");
2683 if(dwStyle & WS_MAXIMIZEBOX)
2684 strcat(style, "WS_MAXIMIZEBOX ");
2685
2686 if(dwExStyle & WS_EX_DLGMODALFRAME)
2687 strcat(exstyle, "WS_EX_DLGMODALFRAME ");
2688 if(dwExStyle & WS_EX_ACCEPTFILES)
2689 strcat(exstyle, "WS_EX_ACCEPTFILES ");
2690 if(dwExStyle & WS_EX_NOPARENTNOTIFY)
2691 strcat(exstyle, "WS_EX_NOPARENTNOTIFY ");
2692 if(dwExStyle & WS_EX_TOPMOST)
2693 strcat(exstyle, "WS_EX_TOPMOST ");
2694 if(dwExStyle & WS_EX_TRANSPARENT)
2695 strcat(exstyle, "WS_EX_TRANSPARENT ");
2696
2697 if(dwExStyle & WS_EX_MDICHILD)
2698 strcat(exstyle, "WS_EX_MDICHILD ");
2699 if(dwExStyle & WS_EX_TOOLWINDOW)
2700 strcat(exstyle, "WS_EX_TOOLWINDOW ");
2701 if(dwExStyle & WS_EX_WINDOWEDGE)
2702 strcat(exstyle, "WS_EX_WINDOWEDGE ");
2703 if(dwExStyle & WS_EX_CLIENTEDGE)
2704 strcat(exstyle, "WS_EX_CLIENTEDGE ");
2705 if(dwExStyle & WS_EX_CONTEXTHELP)
2706 strcat(exstyle, "WS_EX_CONTEXTHELP ");
2707 if(dwExStyle & WS_EX_RIGHT)
2708 strcat(exstyle, "WS_EX_RIGHT ");
2709 if(dwExStyle & WS_EX_LEFT)
2710 strcat(exstyle, "WS_EX_LEFT ");
2711 if(dwExStyle & WS_EX_RTLREADING)
2712 strcat(exstyle, "WS_EX_RTLREADING ");
2713 if(dwExStyle & WS_EX_LTRREADING)
2714 strcat(exstyle, "WS_EX_LTRREADING ");
2715 if(dwExStyle & WS_EX_LEFTSCROLLBAR)
2716 strcat(exstyle, "WS_EX_LEFTSCROLLBAR ");
2717 if(dwExStyle & WS_EX_RIGHTSCROLLBAR)
2718 strcat(exstyle, "WS_EX_RIGHTSCROLLBAR ");
2719 if(dwExStyle & WS_EX_CONTROLPARENT)
2720 strcat(exstyle, "WS_EX_CONTROLPARENT ");
2721 if(dwExStyle & WS_EX_STATICEDGE)
2722 strcat(exstyle, "WS_EX_STATICEDGE ");
2723 if(dwExStyle & WS_EX_APPWINDOW)
2724 strcat(exstyle, "WS_EX_APPWINDOW ");
2725
2726 dprintf(("Window style: %x %s", dwStyle, style));
2727 dprintf(("Window exStyle: %x %s", dwExStyle, exstyle));
2728}
2729#endif
2730//******************************************************************************
2731//******************************************************************************
2732
2733GenericObject *Win32BaseWindow::windows = NULL;
Note: See TracBrowser for help on using the repository browser.