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

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

PostThreadMessage fix

File size: 112.2 KB
Line 
1/* $Id: win32wbase.cpp,v 1.123 1999-12-29 12:39:45 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, 1996 Alexandre Julliard
11 * 1995 Alex Korobka
12 *
13 * TODO: Not thread/process safe
14 *
15 * Project Odin Software License can be found in LICENSE.TXT
16 *
17 */
18#include <os2win.h>
19#include <win.h>
20#include <stdlib.h>
21#include <string.h>
22#include <stdarg.h>
23#include <assert.h>
24#include <misc.h>
25#include <heapstring.h>
26#include <win32wbase.h>
27#include <winres.h>
28#include "wndmsg.h"
29#include "oslibwin.h"
30#include "oslibmsg.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 "dc.h"
39#include "pmframe.h"
40#include "win32wdesktop.h"
41#include "pmwindow.h"
42#include "controls.h"
43#include <wprocess.h>
44#include "winmouse.h"
45#include <win\hook.h>
46#define INCL_TIMERWIN32
47#include "timer.h"
48
49#define HAS_DLGFRAME(style,exStyle) \
50 (((exStyle) & WS_EX_DLGMODALFRAME) || \
51 (((style) & WS_DLGFRAME) && !((style) & WS_THICKFRAME)))
52
53#define HAS_THICKFRAME(style,exStyle) \
54 (((style) & WS_THICKFRAME) && \
55 !((exStyle) & WS_EX_DLGMODALFRAME))
56
57#define HAS_THINFRAME(style) \
58 (((style) & WS_BORDER) || !((style) & (WS_CHILD | WS_POPUP)))
59
60#define HAS_BIGFRAME(style,exStyle) \
61 (((style) & (WS_THICKFRAME | WS_DLGFRAME)) || \
62 ((exStyle) & WS_EX_DLGMODALFRAME))
63
64#define HAS_ANYFRAME(style,exStyle) \
65 (((style) & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) || \
66 ((exStyle) & WS_EX_DLGMODALFRAME) || \
67 !((style) & (WS_CHILD | WS_POPUP)))
68
69#define HAS_3DFRAME(exStyle) \
70 ((exStyle & WS_EX_CLIENTEDGE) || (exStyle & WS_EX_STATICEDGE) || (exStyle & WS_EX_WINDOWEDGE))
71
72#define HAS_BORDER(style, exStyle) \
73 ((style & WS_BORDER) || HAS_THICKFRAME(style) || HAS_DLGFRAME(style,exStyle))
74
75#define IS_OVERLAPPED(style) \
76 !(style & (WS_CHILD | WS_POPUP))
77
78/* bits in the dwKeyData */
79#define KEYDATA_ALT 0x2000
80#define KEYDATA_PREVSTATE 0x4000
81
82void PrintWindowStyle(DWORD dwStyle, DWORD dwExStyle);
83
84static fDestroyAll = FALSE;
85//For quick lookup of current process id
86static ULONG currentProcessId = -1;
87
88//******************************************************************************
89//******************************************************************************
90Win32BaseWindow::Win32BaseWindow(DWORD objType) : GenericObject(&windows, objType)
91{
92 Init();
93}
94//******************************************************************************
95//******************************************************************************
96Win32BaseWindow::Win32BaseWindow(HWND os2Handle,VOID* win32WndProc) : GenericObject(&windows,OBJTYPE_WINDOW)
97{
98 Init();
99 OS2Hwnd = OS2HwndFrame = os2Handle;
100 dwStyle = WS_VISIBLE;
101 setWindowProc((WNDPROC)win32WndProc);
102 fIsSubclassedOS2Wnd = TRUE;
103 fFirstShow = FALSE;
104
105 SetLastError(0);
106
107 //CB: replace by a secure method
108
109 if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, (ULONG)this) == FALSE) {
110 dprintf(("WM_CREATE: WinSetWindowULong %X failed!!", OS2Hwnd));
111 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
112 return;
113 }
114 if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, WIN32PM_MAGIC) == FALSE) {
115 dprintf(("WM_CREATE: WinSetWindowULong2 %X failed!!", OS2Hwnd));
116 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
117 return;
118 }
119
120 OSLibWinQueryWindowRect(OS2Hwnd,&rectWindow);
121 rectClient = rectWindow;
122 rectClient.bottom -= rectClient.top;
123 rectClient.top = 0;
124 rectClient.right -= rectClient.left;
125 rectClient.left = 0;
126
127 setOldWndProc(SubclassWithDefHandler(OS2Hwnd));
128}
129//******************************************************************************
130//******************************************************************************
131Win32BaseWindow::Win32BaseWindow(CREATESTRUCTA *lpCreateStructA, ATOM classAtom, BOOL isUnicode)
132 : GenericObject(&windows, OBJTYPE_WINDOW), ChildWindow()
133{
134 Init();
135 this->isUnicode = isUnicode;
136 CreateWindowExA(lpCreateStructA, classAtom);
137}
138//******************************************************************************
139//******************************************************************************
140void Win32BaseWindow::Init()
141{
142 isUnicode = FALSE;
143 fIsSubclassedOS2Wnd = FALSE;
144 fFirstShow = TRUE;
145 fIsDialog = FALSE;
146 fIsModalDialogOwner = FALSE;
147 OS2HwndModalDialog = 0;
148 fInternalMsg = FALSE;
149 fNoSizeMsg = FALSE;
150 fIsDestroyed = FALSE;
151 fDestroyWindowCalled = FALSE;
152 fCreated = FALSE;
153 fTaskList = FALSE;
154 fParentDC = FALSE;
155
156 windowNameA = NULL;
157 windowNameW = NULL;
158 wndNameLength = 0;
159
160 userWindowLong = NULL;;
161 nrUserWindowLong = 0;
162
163 magic = WIN32PM_MAGIC;
164 OS2Hwnd = 0;
165 OS2HwndFrame = 0;
166 OS2HwndMenu = 0;
167 Win32Hwnd = 0;
168
169 if(HwAllocateWindowHandle(&Win32Hwnd, (ULONG)this) == FALSE)
170 {
171 dprintf(("Win32BaseWindow::Init HwAllocateWindowHandle failed!!"));
172 DebugInt3();
173 }
174
175 posx = posy = 0;
176 width = height = 0;
177
178 dwExStyle = 0;
179 dwStyle = 0;
180 win32wndproc = 0;
181 hInstance = 0;
182 windowId = 0xFFFFFFFF; //default = -1
183 userData = 0;
184 contextHelpId = 0;
185
186 pOldFrameProc = NULL;
187 borderWidth = 0;
188 borderHeight = 0;
189
190 hwndLinkAfter = HWND_BOTTOM;
191 flags = 0;
192 isIcon = FALSE;
193 lastHitTestVal = HTOS_NORMAL;
194 fIgnoreHitTest = FALSE;
195 owner = NULL;
196 windowClass = 0;
197
198 acceltableResource = NULL;
199 iconResource = NULL;
200
201 EraseBkgndFlag = TRUE;
202 PSEraseFlag = FALSE;
203 SuppressEraseFlag = FALSE;
204
205 horzScrollInfo = NULL;
206 vertScrollInfo = NULL;
207 hwndHorzScroll = 0;
208 hwndVertScroll = 0;
209
210 ownDC = 0;
211
212 if(currentProcessId == -1)
213 {
214 currentProcessId = GetCurrentProcessId();
215 }
216 dwThreadId = GetCurrentThreadId();
217 dwProcessId = currentProcessId;
218}
219//******************************************************************************
220//todo get rid of resources (menu, accel, icon etc)
221//******************************************************************************
222Win32BaseWindow::~Win32BaseWindow()
223{
224 OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, 0);
225 OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, 0);
226
227 if(!fDestroyAll && getParent() && getParent()->getFirstChild() == this && getNextChild() == NULL)
228 {
229 //if we're the last child that's being destroyed and our
230 //parent window was also destroyed, then we delete the parent object
231 if(getParent()->IsWindowDestroyed())
232 {
233 dprintf(("Last Child (%x) destroyed, get rid of our parent window (%x)", getWindowHandle(), getParent()->getWindowHandle()));
234 delete getParent();
235 setParent(NULL); //or else we'll crash in the dtor of the ChildWindow class
236 }
237 }
238 else
239 if(fDestroyAll) {
240 dprintf(("Destroying window %x %s", getWindowHandle(), windowNameA));
241 setParent(NULL); //or else we'll crash in the dtor of the ChildWindow class
242 }
243
244 if (isOwnDC())
245 releaseOwnDC (ownDC);
246
247 if(Win32Hwnd)
248 HwFreeWindowHandle(Win32Hwnd);
249
250 if(userWindowLong)
251 free(userWindowLong);
252 if(windowNameA) {
253 free(windowNameA);
254 windowNameA = NULL;
255 }
256 if(windowNameW) {
257 free(windowNameW);
258 windowNameW = NULL;
259 }
260 if(vertScrollInfo) {
261 free(vertScrollInfo);
262 vertScrollInfo = NULL;
263 }
264 if(horzScrollInfo) {
265 free(horzScrollInfo);
266 horzScrollInfo = NULL;
267 }
268}
269//******************************************************************************
270//******************************************************************************
271void Win32BaseWindow::DestroyAll()
272{
273 fDestroyAll = TRUE;
274 GenericObject::DestroyAll(windows);
275}
276//******************************************************************************
277//******************************************************************************
278BOOL Win32BaseWindow::isChild()
279{
280 return ((dwStyle & WS_CHILD) != 0);
281}
282//******************************************************************************
283//******************************************************************************
284BOOL Win32BaseWindow::IsWindowUnicode()
285{
286 dprintf2(("IsWindowUnicode %x %d", getWindowHandle(), WINPROC_GetProcType(getWindowProc()) == WIN_PROC_32W));
287 return (WINPROC_GetProcType(getWindowProc()) == WIN_PROC_32W);
288}
289//******************************************************************************
290//******************************************************************************
291BOOL Win32BaseWindow::CreateWindowExA(CREATESTRUCTA *cs, ATOM classAtom)
292{
293 char buffer[256];
294 POINT maxSize, maxPos, minTrack, maxTrack;
295
296#ifdef DEBUG
297 PrintWindowStyle(cs->style, cs->dwExStyle);
298#endif
299
300 sw = SW_SHOW;
301 SetLastError(0);
302
303 /* Find the parent window */
304 if (cs->hwndParent)
305 {
306 Win32BaseWindow *window = GetWindowFromHandle(cs->hwndParent);
307 if(!window) {
308 dprintf(("Bad parent %04x\n", cs->hwndParent ));
309 SetLastError(ERROR_INVALID_PARAMETER);
310 return FALSE;
311 }
312 /* Make sure parent is valid */
313 if (!window->IsWindow() )
314 {
315 dprintf(("Bad parent %04x\n", cs->hwndParent ));
316 SetLastError(ERROR_INVALID_PARAMETER);
317 return FALSE;
318 }
319 }
320 else
321 if ((cs->style & WS_CHILD) && !(cs->style & WS_POPUP)) {
322 dprintf(("No parent for child window\n" ));
323 SetLastError(ERROR_INVALID_PARAMETER);
324 return FALSE; /* WS_CHILD needs a parent, but WS_POPUP doesn't */
325 }
326
327 /* Find the window class */
328 windowClass = Win32WndClass::FindClass(cs->hInstance, (LPSTR)classAtom);
329 if (!windowClass)
330 {
331 GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) );
332 dprintf(("Bad class '%s'\n", buffer ));
333 SetLastError(ERROR_INVALID_PARAMETER);
334 return 0;
335 }
336#ifdef DEBUG
337 if(HIWORD(cs->lpszClass))
338 {
339 char *astring;
340
341 if(isUnicode) astring = UnicodeToAsciiString((LPWSTR)cs->lpszClass);
342 else astring = (char *)cs->lpszClass;
343
344 dprintf(("Window class %s", astring));
345 if(isUnicode) FreeAsciiString(astring);
346 }
347 else dprintf(("Window class %x", cs->lpszClass));
348#endif
349
350 /* Fix the lpszClass field: from existing programs, it seems ok to call a CreateWindowXXX
351 * with an atom as the class name, put some programs expect to have a *REAL* string in
352 * lpszClass when the CREATESTRUCT is sent with WM_CREATE
353 */
354 if (!HIWORD(cs->lpszClass) ) {
355 if (isUnicode) {
356 GlobalGetAtomNameW( classAtom, (LPWSTR)buffer, sizeof(buffer) );
357 }
358 else {
359 GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) );
360 }
361 cs->lpszClass = buffer;
362 }
363
364 /* Fix the coordinates */
365 if ((cs->x == CW_USEDEFAULT) || (cs->x == CW_USEDEFAULT16))
366 {
367// PDB *pdb = PROCESS_Current();
368
369 /* Never believe Microsoft's documentation... CreateWindowEx doc says
370 * that if an overlapped window is created with WS_VISIBLE style bit
371 * set and the x parameter is set to CW_USEDEFAULT, the system ignores
372 * the y parameter. However, disassembling NT implementation (WIN32K.SYS)
373 * reveals that
374 *
375 * 1) not only if checks for CW_USEDEFAULT but also for CW_USEDEFAULT16
376 * 2) it does not ignore the y parameter as the docs claim; instead, it
377 * uses it as second parameter to ShowWindow() unless y is either
378 * CW_USEDEFAULT or CW_USEDEFAULT16.
379 *
380 * The fact that we didn't do 2) caused bogus windows pop up when wine
381 * was running apps that were using this obscure feature. Example -
382 * calc.exe that comes with Win98 (only Win98, it's different from
383 * the one that comes with Win95 and NT)
384 */
385 if ((cs->y != CW_USEDEFAULT) && (cs->y != CW_USEDEFAULT16)) sw = cs->y;
386
387 /* We have saved cs->y, now we can trash it */
388#if 0
389 if ( !(cs->style & (WS_CHILD | WS_POPUP))
390 && (pdb->env_db->startup_info->dwFlags & STARTF_USEPOSITION) )
391 {
392 cs->x = pdb->env_db->startup_info->dwX;
393 cs->y = pdb->env_db->startup_info->dwY;
394 }
395#endif
396 cs->x = 0;
397 cs->y = 0;
398// }
399 }
400 if ((cs->cx == CW_USEDEFAULT) || (cs->cx == CW_USEDEFAULT16))
401 {
402#if 0
403 PDB *pdb = PROCESS_Current();
404 if ( !(cs->style & (WS_CHILD | WS_POPUP))
405 && (pdb->env_db->startup_info->dwFlags & STARTF_USESIZE) )
406 {
407 cs->cx = pdb->env_db->startup_info->dwXSize;
408 cs->cy = pdb->env_db->startup_info->dwYSize;
409 }
410 else
411 {
412#endif
413 cs->cx = 600; /* FIXME */
414 cs->cy = 400;
415// }
416 }
417
418 if (cs->x < 0) cs->x = 0;
419 if (cs->y < 0) cs->y = 0;
420
421 //Allocate window words
422 nrUserWindowLong = windowClass->getExtraWndWords();
423 if(nrUserWindowLong) {
424 userWindowLong = (ULONG *)_smalloc(nrUserWindowLong);
425 memset(userWindowLong, 0, nrUserWindowLong);
426 }
427
428 if ((cs->style & WS_CHILD) && cs->hwndParent)
429 {
430 SetParent(cs->hwndParent);
431 owner = GetWindowFromHandle(cs->hwndParent);
432 if(owner == NULL)
433 {
434 dprintf(("HwGetWindowHandleData couldn't find owner window %x!!!", cs->hwndParent));
435 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
436 return FALSE;
437 }
438 }
439 else
440 {
441 SetParent(0);
442 if (!cs->hwndParent || (cs->hwndParent == windowDesktop->getWindowHandle())) {
443 owner = NULL;
444 }
445 else
446 {
447 owner = GetWindowFromHandle(cs->hwndParent)->GetTopParent();
448 if(owner == NULL)
449 {
450 dprintf(("HwGetWindowHandleData couldn't find owner window %x!!!", cs->hwndParent));
451 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
452 return FALSE;
453 }
454 }
455 }
456
457 WINPROC_SetProc((HWINDOWPROC *)&win32wndproc, windowClass->getWindowProc(), WINPROC_GetProcType(windowClass->getWindowProc()), WIN_PROC_WINDOW);
458 hInstance = cs->hInstance;
459 dwStyle = cs->style & ~WS_VISIBLE;
460 dwExStyle = cs->dwExStyle;
461
462 hwndLinkAfter = HWND_TOP;
463 if(WIDGETS_IsControl(this, BUTTON_CONTROL) && ((dwStyle & 0x0f) == BS_GROUPBOX))
464 {
465 hwndLinkAfter = HWND_BOTTOM;
466 dwStyle |= WS_CLIPSIBLINGS;
467 }
468 else
469 if(WIDGETS_IsControl(this, STATIC_CONTROL) && !(dwStyle & WS_GROUP)) {
470 dwStyle |= WS_CLIPSIBLINGS;
471 }
472
473 /* Increment class window counter */
474 windowClass->IncreaseWindowCount();
475
476 if (HOOK_IsHooked( WH_CBT ))
477 {
478 CBT_CREATEWNDA cbtc;
479 LRESULT ret;
480
481 cbtc.lpcs = cs;
482 cbtc.hwndInsertAfter = hwndLinkAfter;
483 ret = HOOK_CallHooksA(WH_CBT, HCBT_CREATEWND, getWindowHandle(), (LPARAM)&cbtc);
484 if(ret)
485 {
486 dprintf(("CBT-hook returned 0!!"));
487 SetLastError(ERROR_CAN_NOT_COMPLETE); //todo: wrong error
488 return FALSE;
489 }
490 }
491
492 /* Correct the window style */
493 if (!(cs->style & WS_CHILD))
494 {
495 dwStyle |= WS_CLIPSIBLINGS;
496 if (!(cs->style & WS_POPUP))
497 {
498 dwStyle |= WS_CAPTION;
499 flags |= WIN_NEED_SIZE;
500 }
501 }
502 if (cs->dwExStyle & WS_EX_DLGMODALFRAME) dwStyle &= ~WS_THICKFRAME;
503
504 if (cs->style & WS_HSCROLL)
505 {
506 horzScrollInfo = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
507 horzScrollInfo->MinVal = horzScrollInfo->CurVal = horzScrollInfo->Page = 0;
508 horzScrollInfo->MaxVal = 100;
509 horzScrollInfo->flags = ESB_ENABLE_BOTH;
510 }
511
512 if (cs->style & WS_VSCROLL)
513 {
514 vertScrollInfo = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
515 vertScrollInfo->MinVal = vertScrollInfo->CurVal = vertScrollInfo->Page = 0;
516 vertScrollInfo->MaxVal = 100;
517 vertScrollInfo->flags = ESB_ENABLE_BOTH;
518 }
519
520 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
521 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
522 {
523 GetMinMaxInfo(&maxSize, &maxPos, &minTrack, &maxTrack);
524 if (maxSize.x < cs->cx) cs->cx = maxSize.x;
525 if (maxSize.y < cs->cy) cs->cy = maxSize.y;
526 if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
527 if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
528 }
529
530 if(cs->style & WS_CHILD)
531 {
532 if(cs->cx < 0) cs->cx = 0;
533 if(cs->cy < 0) cs->cy = 0;
534 }
535 else
536 {
537 if (cs->cx <= 0) cs->cx = 1;
538 if (cs->cy <= 0) cs->cy = 1;
539 }
540
541 if(((dwStyle & 0xC0000000) == WS_OVERLAPPED) && ((dwStyle & WS_CAPTION) == WS_CAPTION) && owner == NULL
542 && dwStyle & WS_SYSMENU)
543 {
544 fTaskList = TRUE;
545 }
546
547 DWORD dwOSWinStyle, dwOSFrameStyle;
548
549 OSLibWinConvertStyle(dwStyle, &dwExStyle, &dwOSWinStyle, &dwOSFrameStyle, &borderWidth, &borderHeight);
550
551 if(HIWORD(cs->lpszName))
552 {
553 if (!isUnicode)
554 {
555 wndNameLength = strlen(cs->lpszName);
556 windowNameA = (LPSTR)_smalloc(wndNameLength+1);
557 strcpy(windowNameA,cs->lpszName);
558 windowNameW = (LPWSTR)_smalloc((wndNameLength+1)*sizeof(WCHAR));
559 lstrcpyAtoW(windowNameW,windowNameA);
560 windowNameA[wndNameLength] = 0;
561 windowNameW[wndNameLength] = 0;
562 }
563 else
564 {
565 wndNameLength = lstrlenW((LPWSTR)cs->lpszName);
566 windowNameA = (LPSTR)_smalloc(wndNameLength+1);
567 lstrcpyWtoA(windowNameA,(LPWSTR)cs->lpszName);
568 windowNameW = (LPWSTR)_smalloc((wndNameLength+1)*sizeof(WCHAR));
569 lstrcpyW(windowNameW,(LPWSTR)cs->lpszName);
570 windowNameA[wndNameLength] = 0;
571 windowNameW[wndNameLength] = 0;
572 }
573 }
574
575 //copy pointer of CREATESTRUCT for usage in MsgCreate method
576 tmpcs = cs;
577
578 //Store our window object pointer in thread local memory, so PMWINDOW.CPP can retrieve it
579 THDB *thdb = GetThreadTHDB();
580
581 if(thdb == NULL) {
582 dprintf(("Window creation failed - thdb == NULL")); //this is VERY bad
583 ExitProcess(666);
584 return FALSE;
585 }
586
587 thdb->newWindow = (ULONG)this;
588
589 OS2Hwnd = OSLibWinCreateWindow((getParent()) ? getParent()->getOS2WindowHandle() : OSLIB_HWND_DESKTOP,
590 dwOSWinStyle, dwOSFrameStyle, (char *)windowNameA,
591 (owner) ? owner->getOS2WindowHandle() : OSLIB_HWND_DESKTOP,
592 (hwndLinkAfter == HWND_BOTTOM) ? TRUE : FALSE,
593 &OS2HwndFrame, 0, fTaskList);
594
595 if(OS2Hwnd == 0) {
596 dprintf(("Window creation failed!!"));
597 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
598 return FALSE;
599 }
600
601 SetLastError(0);
602 return TRUE;
603}
604//******************************************************************************
605//******************************************************************************
606BOOL Win32BaseWindow::MsgCreate(HWND hwndFrame, HWND hwndClient)
607{
608 POINT maxPos;
609 CREATESTRUCTA *cs = tmpcs; //pointer to CREATESTRUCT used in CreateWindowExA method
610
611 OS2Hwnd = hwndClient;
612 OS2HwndFrame = hwndFrame;
613
614 fNoSizeMsg = TRUE;
615
616 if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32WNDPTR, (ULONG)this) == FALSE) {
617 dprintf(("WM_CREATE: WinSetWindowULong %X failed!!", OS2Hwnd));
618 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
619 return FALSE;
620 }
621 if(OSLibWinSetWindowULong(OS2Hwnd, OFFSET_WIN32PM_MAGIC, WIN32PM_MAGIC) == FALSE) {
622 dprintf(("WM_CREATE: WinSetWindowULong2 %X failed!!", OS2Hwnd));
623 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
624 return FALSE;
625 }
626#if 0
627 if(OS2Hwnd != OS2HwndFrame) {
628 if(OSLibWinSetWindowULong(OS2HwndFrame, OFFSET_WIN32WNDPTR, (ULONG)this) == FALSE) {
629 dprintf(("WM_CREATE: WinSetWindowULong %X failed!!", OS2HwndFrame));
630 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
631 return FALSE;
632 }
633 if(OSLibWinSetWindowULong(OS2HwndFrame, OFFSET_WIN32PM_MAGIC, WIN32PM_MAGIC) == FALSE) {
634 dprintf(("WM_CREATE: WinSetWindowULong2 %X failed!!", OS2HwndFrame));
635 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
636 return FALSE;
637 }
638 }
639#endif
640
641 OSLibWinSetOwner(OS2Hwnd, OS2HwndFrame);
642
643 FrameGetScrollBarHandles(this,dwStyle & WS_HSCROLL,dwStyle & WS_VSCROLL);
644 subclassScrollBars(dwStyle & WS_HSCROLL,dwStyle & WS_VSCROLL);
645
646 fakeWinBase.hwndThis = OS2Hwnd;
647 fakeWinBase.pWindowClass = windowClass;
648
649 //Set icon from class
650 if(windowClass->getIcon())
651 SetIcon(windowClass->getIcon());
652
653 /* Get class or window DC if needed */
654 if(windowClass->getStyle() & CS_OWNDC) {
655 dprintf(("Class with CS_OWNDC style"));
656// ownDC = GetWindowDC(getWindowHandle());
657 }
658 else
659 if (windowClass->getStyle() & CS_PARENTDC) {
660 dprintf(("WARNING: Class with CS_PARENTDC style!"));
661 fParentDC = TRUE;
662 ownDC = 0;
663 }
664 else
665 if (windowClass->getStyle() & CS_CLASSDC) {
666 dprintf(("WARNING: Class with CS_CLASSDC style!"));
667 ownDC = 0;
668 }
669 /* Set the window menu */
670 if ((dwStyle & (WS_CAPTION | WS_CHILD)) == WS_CAPTION )
671 {
672 if (cs->hMenu) {
673 SetMenu(cs->hMenu);
674 }
675 else {
676 if (windowClass->getMenuNameA()) {
677 cs->hMenu = LoadMenuA(cs->hInstance, windowClass->getMenuNameA());
678 if (cs->hMenu) SetMenu(cs->hMenu );
679 }
680 }
681 }
682 else
683 {
684 setWindowId((DWORD)cs->hMenu);
685 }
686
687 // Subclass frame
688 pOldFrameProc = FrameSubclassFrameWindow(this);
689 if (isChild()) FrameSetBorderSize(this,TRUE);
690
691 /* Send the WM_CREATE message
692 * Perhaps we shouldn't allow width/height changes as well.
693 * See p327 in "Internals".
694 */
695 maxPos.x = rectWindow.left; maxPos.y = rectWindow.top;
696
697 SetWindowPos(hwndLinkAfter,cs->x,cs->y,cs->cx,cs->cy,SWP_NOACTIVATE | SWP_NOREDRAW);
698
699 //Note: Solitaire crashes when receiving WM_SIZE messages before WM_CREATE
700 fNoSizeMsg = FALSE;
701
702 if(SendInternalMessageA(WM_NCCREATE, 0, (LPARAM)cs) )
703 {
704 fCreated = TRUE;
705
706 SendNCCalcSize(FALSE, &rectWindow, NULL, NULL, 0, &rectClient );
707// OffsetRect(&rectWindow, maxPos.x - rectWindow.left, maxPos.y - rectWindow.top);
708 if( (SendInternalMessageA(WM_CREATE, 0, (LPARAM)cs )) != -1 )
709 {
710 if(!(flags & WIN_NEED_SIZE)) {
711 SendInternalMessageA(WM_SIZE, SIZE_RESTORED,
712 MAKELONG(rectClient.right-rectClient.left,
713 rectClient.bottom-rectClient.top));
714 SendInternalMessageA(WM_MOVE, 0, MAKELONG( rectClient.left, rectClient.top ) );
715 }
716
717 if( getStyle() & WS_CHILD && !(getExStyle() & WS_EX_NOPARENTNOTIFY) )
718 {
719 /* Notify the parent window only */
720 SendInternalMessageA(WM_PARENTNOTIFY, MAKEWPARAM(WM_CREATE, getWindowId()), (LPARAM)getWindowHandle());
721 if(!::IsWindow(getWindowHandle()))
722 {
723 dprintf(("Createwindow: WM_PARENTNOTIFY destroyed window"));
724 goto end;
725 }
726 }
727
728 if (cs->style & WS_VISIBLE) ShowWindow( sw );
729
730 /* Call WH_SHELL hook */
731 if (!(getStyle() & WS_CHILD) && !owner)
732 HOOK_CallHooksA(WH_SHELL, HSHELL_WINDOWCREATED, getWindowHandle(), 0 );
733
734 SetLastError(0);
735 return TRUE;
736 }
737 }
738 dprintf(("Window creation FAILED (NCCREATE cancelled creation)"));
739 SetLastError(ERROR_OUTOFMEMORY); //TODO: Better error
740end:
741 return FALSE;
742}
743//******************************************************************************
744//******************************************************************************
745ULONG Win32BaseWindow::MsgQuit()
746{
747 return SendInternalMessageA(WM_QUIT, 0, 0);
748}
749//******************************************************************************
750//******************************************************************************
751ULONG Win32BaseWindow::MsgClose()
752{
753 return SendInternalMessageA(WM_CLOSE,0,0);
754}
755//******************************************************************************
756//******************************************************************************
757ULONG Win32BaseWindow::MsgDestroy()
758{
759 ULONG rc;
760 Win32BaseWindow *child;
761 HWND hwnd = getWindowHandle();
762
763 if (isSubclassedOS2Wnd) OSLibWinSubclassWindow(OS2Hwnd,pOldWndProc);
764
765 fIsDestroyed = TRUE;
766
767 if(fDestroyWindowCalled == FALSE)
768 {//this window was destroyed because DestroyWindow was called for it's parent
769 //so: send a WM_PARENTNOTIFY now as that hasn't happened yet
770 if((getStyle() & WS_CHILD) && !(getExStyle() & WS_EX_NOPARENTNOTIFY))
771 {
772 if(getParent())
773 {
774 /* Notify the parent window only */
775 getParent()->SendMessageA(WM_PARENTNOTIFY, MAKEWPARAM(WM_DESTROY, getWindowId()), (LPARAM)getWindowHandle());
776 }
777 else DebugInt3();
778 }
779 }
780 SendInternalMessageA(WM_DESTROY, 0, 0);
781 if(::IsWindow(hwnd) == FALSE) {
782 //object already destroyed, so return immediately
783 return 1;
784 }
785 SendInternalMessageA(WM_NCDESTROY, 0, 0);
786
787 if (hwndHorzScroll && (OSLibWinQueryWindow(hwndHorzScroll,QWOS_PARENT) == OSLibWinQueryObjectWindow())) OSLibWinDestroyWindow(hwndHorzScroll);
788 if (hwndVertScroll && (OSLibWinQueryWindow(hwndVertScroll,QWOS_PARENT) == OSLibWinQueryObjectWindow())) OSLibWinDestroyWindow(hwndVertScroll);
789
790 TIMER_KillTimerFromWindow(OS2Hwnd);
791
792 if(getFirstChild() == NULL) {
793 delete this;
794 }
795 return 1;
796}
797//******************************************************************************
798//******************************************************************************
799ULONG Win32BaseWindow::MsgEnable(BOOL fEnable)
800{
801 if(fEnable) {
802 dwStyle &= ~WS_DISABLED;
803 }
804 else dwStyle |= WS_DISABLED;
805
806 return SendInternalMessageA(WM_ENABLE, fEnable, 0);
807}
808//******************************************************************************
809//TODO: SW_PARENTCLOSING/OPENING flag (lParam)
810//******************************************************************************
811ULONG Win32BaseWindow::MsgShow(BOOL fShow)
812{
813 if(fNoSizeMsg) {
814 return 1;
815 }
816
817 if(fShow) {
818 setStyle(getStyle() | WS_VISIBLE);
819 }
820 else setStyle(getStyle() & ~WS_VISIBLE);
821
822 return SendInternalMessageA(WM_SHOWWINDOW, fShow, 0);
823}
824//******************************************************************************
825//******************************************************************************
826ULONG Win32BaseWindow::MsgPosChanging(LPARAM lp)
827{
828 if(fNoSizeMsg)
829 return 1;
830
831 return SendInternalMessageA(WM_WINDOWPOSCHANGING, 0, lp);
832}
833//******************************************************************************
834//******************************************************************************
835ULONG Win32BaseWindow::MsgPosChanged(LPARAM lp)
836{
837 if(fNoSizeMsg)
838 return 1;
839
840 return SendInternalMessageA(WM_WINDOWPOSCHANGED, 0, lp);
841}
842//******************************************************************************
843//******************************************************************************
844#if 0
845ULONG Win32BaseWindow::MsgMinMax()
846{
847
848}
849#endif
850//******************************************************************************
851//******************************************************************************
852ULONG Win32BaseWindow::MsgScroll(ULONG msg, ULONG scrollCode, ULONG scrollPos)
853{
854 //According to the SDK docs, the scrollbar handle (lParam) is 0 when the standard
855 //window scrollbars send these messages
856 return SendInternalMessageA(msg, MAKELONG(scrollCode, scrollPos), 0);
857}
858//******************************************************************************
859//******************************************************************************
860ULONG Win32BaseWindow::MsgHitTest(MSG *msg)
861{
862 lastHitTestVal = SendInternalMessageA(WM_NCHITTEST, 0, MAKELONG((USHORT)msg->pt.x, (USHORT)msg->pt.y));
863 dprintf2(("MsgHitTest returned %x", lastHitTestVal));
864
865 if (lastHitTestVal == HTERROR)
866 return HTOS_ERROR;
867
868#if 0 //CB: problems with groupboxes, internal handling is better
869 if (lastHitTestVal == HTTRANSPARENT)
870 return HTOS_TRANSPARENT;
871#endif
872
873 return HTOS_NORMAL;
874}
875//******************************************************************************
876//******************************************************************************
877ULONG Win32BaseWindow::MsgActivate(BOOL fActivate, BOOL fMinimized, HWND hwnd)
878{
879 ULONG rc, curprocid, procidhwnd = -1, threadidhwnd = 0;
880
881
882 //According to SDK docs, if app returns FALSE & window is being deactivated,
883 //default processing is cancelled
884 //TODO: According to Wine we should proceed anyway if window is sysmodal
885 if(SendInternalMessageA(WM_NCACTIVATE, fActivate, 0) == FALSE && !fActivate)
886 {
887 return 0;
888 }
889 rc = SendInternalMessageA(WM_ACTIVATE, MAKELONG((fActivate) ? WA_ACTIVE : WA_INACTIVE, fMinimized), hwnd);
890
891 curprocid = GetCurrentProcessId();
892 if(hwnd) {
893 threadidhwnd = GetWindowThreadProcessId(hwnd, &procidhwnd);
894 }
895
896 if(curprocid != procidhwnd && fActivate) {
897 SendInternalMessageA(WM_ACTIVATEAPP, 1, threadidhwnd);
898 }
899 return rc;
900}
901//******************************************************************************
902//TODO: Is this correct and complete?
903//Add print screen, break & numlock
904//******************************************************************************
905void Win32BaseWindow::setExtendedKey(ULONG virtualkey, ULONG *lParam)
906{
907 switch(virtualkey) {
908 case VK_DOWN:
909 case VK_UP:
910 case VK_PRIOR:
911 case VK_NEXT:
912 case VK_END:
913 case VK_DIVIDE:
914 case VK_DELETE:
915 case VK_EXECUTE: //Numeric enter key?
916 case VK_HOME:
917 case VK_INSERT:
918 case VK_RCONTROL:
919 case VK_RMENU: //is this the right alt???
920 *lParam = *lParam | (1<<24);
921 }
922}
923//******************************************************************************
924//******************************************************************************
925ULONG Win32BaseWindow::DispatchMsg(MSG *msg)
926{
927 return SendInternalMessageA(msg->message, msg->wParam, msg->lParam);
928}
929//******************************************************************************
930//******************************************************************************
931ULONG Win32BaseWindow::MsgSetFocus(HWND hwnd)
932{
933 return SendInternalMessageA(WM_SETFOCUS, hwnd, 0);
934}
935//******************************************************************************
936//******************************************************************************
937ULONG Win32BaseWindow::MsgKillFocus(HWND hwnd)
938{
939 return SendInternalMessageA(WM_KILLFOCUS, hwnd, 0);
940}
941//******************************************************************************
942//******************************************************************************
943ULONG Win32BaseWindow::MsgButton(MSG *msg)
944{
945 BOOL fClick = FALSE;
946
947 dprintf(("MsgButton at (%d,%d)", msg->pt.x, msg->pt.y));
948 switch(msg->message) {
949 case WM_LBUTTONDBLCLK:
950 case WM_RBUTTONDBLCLK:
951 case WM_MBUTTONDBLCLK:
952 case WM_NCLBUTTONDBLCLK:
953 case WM_NCRBUTTONDBLCLK:
954 case WM_NCMBUTTONDBLCLK:
955 if (!(windowClass && windowClass->getClassLongA(GCL_STYLE) & CS_DBLCLKS))
956 {
957 msg->message = msg->message - (WM_LBUTTONDBLCLK - WM_LBUTTONDOWN); //dblclick -> down
958 MsgButton(msg);
959 msg->message++; //button-up
960 return MsgButton(msg);
961 }
962 break;
963 case WM_LBUTTONDOWN:
964 case WM_RBUTTONDOWN:
965 case WM_MBUTTONDOWN:
966 case WM_NCLBUTTONDOWN:
967 case WM_NCRBUTTONDOWN:
968 case WM_NCMBUTTONDOWN:
969 fClick = TRUE;
970 break;
971 }
972
973 if(ISMOUSE_CAPTURED())
974 {
975 if(DInputMouseHandler(getWindowHandle(), MOUSEMSG_BUTTON, msg->pt.x, msg->pt.y))
976 return 0;
977 }
978
979 if(fClick)
980 {
981 HWND hwndTop;
982
983 /* Activate the window if needed */
984 if(isSubclassedOS2Wnd()) {
985 Win32BaseWindow *parentwnd = GetWindowFromOS2FrameHandle(OSLibWinQueryWindow(OS2Hwnd, QWOS_PARENT));
986 if(parentwnd) {
987 hwndTop = (parentwnd->GetTopParent()) ? parentwnd->GetTopParent()->getWindowHandle() : 0;
988 }
989 else hwndTop = 0;
990 }
991 else hwndTop = (GetTopParent()) ? GetTopParent()->getWindowHandle() : 0;
992
993 HWND hwndActive = GetActiveWindow();
994 if (hwndTop && (getWindowHandle() != hwndActive))
995 {
996 LONG ret = SendInternalMessageA(WM_MOUSEACTIVATE, hwndTop,
997 MAKELONG( lastHitTestVal, msg->message) );
998
999#if 0
1000 if ((ret == MA_ACTIVATEANDEAT) || (ret == MA_NOACTIVATEANDEAT))
1001 eatMsg = TRUE;
1002#endif
1003 if(((ret == MA_ACTIVATE) || (ret == MA_ACTIVATEANDEAT))
1004 && hwndTop != GetForegroundWindow() )
1005 {
1006 ::SetActiveWindow(hwndTop);
1007 }
1008 }
1009 }
1010
1011 SendInternalMessageA(WM_SETCURSOR, getWindowHandle(), MAKELONG(lastHitTestVal, msg->message));
1012
1013 return SendInternalMessageA(msg->message, msg->wParam, msg->lParam);
1014}
1015//******************************************************************************
1016//******************************************************************************
1017ULONG Win32BaseWindow::MsgPaint(ULONG tmp1, BOOL select)
1018{
1019 if (select && isIcon)
1020 return SendInternalMessageA(WM_PAINTICON, 0, 0);
1021 else
1022 return SendInternalMessageA(WM_PAINT, 0, 0);
1023}
1024//******************************************************************************
1025//TODO: Is the clipper region of the window DC equal to the invalidated rectangle?
1026// (or are we simply erasing too much here)
1027//******************************************************************************
1028ULONG Win32BaseWindow::MsgEraseBackGround(HDC hdc)
1029{
1030 ULONG rc;
1031 HDC hdcErase = hdc;
1032
1033 if (hdcErase == 0)
1034 hdcErase = O32_GetDC(OS2Hwnd);
1035
1036 if(isIcon)
1037 rc = SendInternalMessageA(WM_ICONERASEBKGND, hdcErase, 0);
1038 else
1039 rc = SendInternalMessageA(WM_ERASEBKGND, hdcErase, 0);
1040 if (hdc == 0)
1041 O32_ReleaseDC(OS2Hwnd, hdcErase);
1042 return (rc);
1043}
1044//******************************************************************************
1045//******************************************************************************
1046ULONG Win32BaseWindow::MsgMouseMove(MSG *msg)
1047{
1048 if(ISMOUSE_CAPTURED()) {
1049 if(DInputMouseHandler(getWindowHandle(), MOUSEMSG_MOVE, msg->pt.x, msg->pt.y))
1050 return 0;
1051 }
1052
1053 //TODO: hiword should be 0 if window enters menu mode (SDK docs)
1054 SendInternalMessageA(WM_SETCURSOR, Win32Hwnd, MAKELONG(lastHitTestVal, msg->message));
1055
1056 //translated message == WM_(NC)MOUSEMOVE
1057 return SendInternalMessageA(msg->message, msg->wParam, msg->lParam);
1058}
1059//******************************************************************************
1060//TODO: Depending on menu type, we should send WM_INITMENU or WM_INITPOPUPMENU
1061//TODO: PM sends it for each submenu that gets activated; Windows only for the first
1062// submenu; once the menu bar is active, moving the cursor doesn't generate other
1063// WM_INITMENU msgs. Not really a problem, but might need to fix this later on.
1064//******************************************************************************
1065ULONG Win32BaseWindow::MsgInitMenu(MSG *msg)
1066{
1067 return SendInternalMessageA(msg->message, msg->wParam, msg->lParam);
1068}
1069//******************************************************************************
1070//******************************************************************************
1071ULONG Win32BaseWindow::MsgNCPaint()
1072{
1073 return SendInternalMessageA(WM_PAINT, 0, 0);
1074}
1075//******************************************************************************
1076//******************************************************************************
1077ULONG Win32BaseWindow::MsgSetText(LPSTR lpsz, LONG cch)
1078{
1079 return SendInternalMessageA(WM_SETTEXT, 0, (LPARAM)lpsz);
1080}
1081//******************************************************************************
1082//******************************************************************************
1083ULONG Win32BaseWindow::MsgGetTextLength()
1084{
1085 return SendInternalMessageA(WM_GETTEXTLENGTH, 0, 0);
1086}
1087//******************************************************************************
1088//******************************************************************************
1089char *Win32BaseWindow::MsgGetText()
1090{
1091 SendInternalMessageA(WM_GETTEXT, wndNameLength, (LPARAM)windowNameA);
1092 return windowNameA;
1093}
1094//******************************************************************************
1095//******************************************************************************
1096ULONG Win32BaseWindow::MsgContextMenu(ULONG x,ULONG y)
1097{
1098 return SendInternalMessageA(WM_CONTEXTMENU,Win32Hwnd,MAKELPARAM(x,y));
1099}
1100//******************************************************************************
1101//******************************************************************************
1102BOOL Win32BaseWindow::isMDIClient()
1103{
1104 return FALSE;
1105}
1106//******************************************************************************
1107//******************************************************************************
1108BOOL Win32BaseWindow::isMDIChild()
1109{
1110 return FALSE;
1111}
1112//******************************************************************************
1113//TODO: Not complete
1114//******************************************************************************
1115BOOL Win32BaseWindow::isFrameWindow()
1116{
1117// if(isMDIChild() || IsDialog() || (getParent() == NULL || getParent() == windowDesktop) && ((dwStyle & WS_CAPTION) == WS_CAPTION))
1118 if((dwStyle & WS_CAPTION) == WS_CAPTION || dwStyle & (WS_VSCROLL|WS_HSCROLL))
1119 return TRUE;
1120
1121 return FALSE;
1122}
1123//******************************************************************************
1124//******************************************************************************
1125SCROLLBAR_INFO *Win32BaseWindow::getScrollInfo(int nBar)
1126{
1127 switch(nBar)
1128 {
1129 case SB_HORZ:
1130 return horzScrollInfo;
1131
1132 case SB_VERT:
1133 return vertScrollInfo;
1134 }
1135
1136 return NULL;
1137}
1138//******************************************************************************
1139//******************************************************************************
1140VOID Win32BaseWindow::subclassScrollBars(BOOL subHorz,BOOL subVert)
1141{
1142 SCROLL_SubclassScrollBars(subHorz ? hwndHorzScroll:0,subVert ? hwndVertScroll:0);
1143}
1144//******************************************************************************
1145//******************************************************************************
1146BOOL Win32BaseWindow::showScrollBars(BOOL changeHorz,BOOL changeVert,BOOL fShow)
1147{
1148 BOOL rc = TRUE;
1149 DWORD flags = 0;
1150
1151 if (fShow)
1152 {
1153 BOOL createHorz = FALSE,createVert = FALSE;
1154 BOOL showHorz = FALSE,showVert = FALSE;
1155
1156 if (changeHorz)
1157 {
1158 if (!hwndHorzScroll)
1159 createHorz = TRUE;
1160 else
1161 showHorz = TRUE;
1162 }
1163
1164 if (changeVert)
1165 {
1166 if (!hwndVertScroll)
1167 createVert = TRUE;
1168 else
1169 showVert = TRUE;
1170 }
1171
1172 if (createHorz || createVert)
1173 {
1174 if (createHorz && !horzScrollInfo)
1175 {
1176 horzScrollInfo = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
1177 horzScrollInfo->MinVal = horzScrollInfo->CurVal = horzScrollInfo->Page = 0;
1178 horzScrollInfo->MaxVal = 100;
1179 horzScrollInfo->flags = ESB_ENABLE_BOTH;
1180 }
1181
1182 if (createVert && !vertScrollInfo)
1183 {
1184 vertScrollInfo = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
1185 vertScrollInfo->MinVal = vertScrollInfo->CurVal = vertScrollInfo->Page = 0;
1186 vertScrollInfo->MaxVal = 100;
1187 vertScrollInfo->flags = ESB_ENABLE_BOTH;
1188 }
1189
1190 rc = FrameCreateScrollBars(this,createHorz,createVert,FALSE,&flags);
1191
1192 if (!rc) return FALSE;
1193 if (createHorz) dwStyle |= WS_HSCROLL;
1194 if (createVert) dwStyle |= WS_VSCROLL;
1195 }
1196
1197 if (showVert || showHorz)
1198 {
1199 DWORD newFlags;
1200
1201 rc = FrameShowScrollBars(this,showHorz,showVert,fShow,FALSE,&newFlags);
1202 flags |= newFlags;
1203 if (rc)
1204 {
1205 if (showHorz) dwStyle |= WS_HSCROLL;
1206 if (showVert) dwStyle |= WS_VSCROLL;
1207 }
1208 }
1209
1210 if (flags) FrameUpdateFrame(this,flags);
1211 } else
1212 {
1213 rc = FrameShowScrollBars(this,changeHorz && hwndHorzScroll,changeVert && hwndVertScroll,fShow,TRUE);
1214
1215 if (rc)
1216 {
1217 if (changeHorz) dwStyle &= ~WS_HSCROLL;
1218 if (changeVert) dwStyle &= ~WS_VSCROLL;
1219 }
1220 }
1221
1222 return rc;
1223}
1224/***********************************************************************
1225 * NC_HandleNCLButtonDown
1226 *
1227 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
1228 */
1229LONG Win32BaseWindow::HandleNCLButtonDown(WPARAM wParam,LPARAM lParam)
1230{
1231 switch(wParam) /* Hit test */
1232 {
1233 case HTCAPTION:
1234 SendInternalMessageA(WM_SYSCOMMAND,SC_MOVE+HTCAPTION,lParam);
1235 break;
1236
1237 case HTSYSMENU:
1238 SendInternalMessageA(WM_SYSCOMMAND,SC_MOUSEMENU+HTSYSMENU,lParam);
1239 break;
1240
1241 case HTMENU:
1242 SendInternalMessageA(WM_SYSCOMMAND,SC_MOUSEMENU,lParam);
1243 break;
1244
1245 case HTHSCROLL:
1246 SendInternalMessageA(WM_SYSCOMMAND,SC_HSCROLL+HTHSCROLL,lParam);
1247 break;
1248
1249 case HTVSCROLL:
1250 SendInternalMessageA(WM_SYSCOMMAND,SC_VSCROLL+HTVSCROLL,lParam);
1251 break;
1252
1253 case HTLEFT:
1254 case HTRIGHT:
1255 case HTTOP:
1256 case HTTOPLEFT:
1257 case HTTOPRIGHT:
1258 case HTBOTTOM:
1259 case HTBOTTOMLEFT:
1260 case HTBOTTOMRIGHT:
1261 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
1262 SendInternalMessageA(WM_SYSCOMMAND,SC_SIZE+wParam-2,lParam);
1263 break;
1264 case HTBORDER:
1265 break;
1266 }
1267
1268 return 0;
1269}
1270//******************************************************************************
1271//******************************************************************************
1272LONG Win32BaseWindow::HandleNCLButtonUp(WPARAM wParam,LPARAM lParam)
1273{
1274 switch(wParam) /* Hit test */
1275 {
1276 case HTMINBUTTON:
1277 SendInternalMessageA(WM_SYSCOMMAND,SC_MINIMIZE,lParam);
1278 break;
1279
1280 case HTMAXBUTTON:
1281 SendInternalMessageA(WM_SYSCOMMAND,SC_MAXIMIZE,lParam);
1282 break;
1283
1284 case HTCLOSE:
1285 SendInternalMessageA(WM_SYSCOMMAND,SC_CLOSE,lParam);
1286 break;
1287 }
1288
1289 return 0;
1290}
1291/***********************************************************************
1292 * NC_HandleNCLButtonDblClk
1293 *
1294 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
1295 */
1296LONG Win32BaseWindow::HandleNCLButtonDblClk(WPARAM wParam,LPARAM lParam)
1297{
1298 /*
1299 * if this is an icon, send a restore since we are handling
1300 * a double click
1301 */
1302 if (dwStyle & WS_MINIMIZE)
1303 {
1304 SendInternalMessageA(WM_SYSCOMMAND,SC_RESTORE,lParam);
1305 return 0;
1306 }
1307
1308 switch(wParam) /* Hit test */
1309 {
1310 case HTCAPTION:
1311 /* stop processing if WS_MAXIMIZEBOX is missing */
1312 if (dwStyle & WS_MAXIMIZEBOX)
1313 SendInternalMessageA(WM_SYSCOMMAND,
1314 (dwStyle & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE,
1315 lParam);
1316 break;
1317
1318 case HTSYSMENU:
1319 if (!(GetClassWord(Win32Hwnd,GCW_STYLE) & CS_NOCLOSE))
1320 SendInternalMessageA(WM_SYSCOMMAND,SC_CLOSE,lParam);
1321 break;
1322
1323 case HTHSCROLL:
1324 SendInternalMessageA(WM_SYSCOMMAND,SC_HSCROLL+HTHSCROLL,lParam);
1325 break;
1326
1327 case HTVSCROLL:
1328 SendInternalMessageA(WM_SYSCOMMAND,SC_VSCROLL+HTVSCROLL,lParam);
1329 break;
1330 }
1331
1332 return 0;
1333}
1334/***********************************************************************
1335 * NC_HandleSysCommand
1336 *
1337 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
1338 *
1339 * TODO: Not done (see #if 0)
1340 */
1341LONG Win32BaseWindow::HandleSysCommand(WPARAM wParam, POINT *pt32)
1342{
1343 UINT uCommand = wParam & 0xFFF0;
1344
1345 if ((getStyle() & WS_CHILD) && (uCommand != SC_KEYMENU))
1346 ScreenToClient(getParent()->getWindowHandle(), pt32 );
1347
1348 switch (uCommand)
1349 {
1350
1351 case SC_SIZE:
1352 {
1353 DWORD flags = 0;
1354
1355 switch ((wParam & 0xF)+2)
1356 {
1357 case HTLEFT:
1358 flags = TFOS_LEFT;
1359 break;
1360
1361 case HTRIGHT:
1362 flags = TFOS_RIGHT;
1363 break;
1364
1365 case HTTOP:
1366 flags = TFOS_TOP;
1367 break;
1368
1369 case HTTOPLEFT:
1370 flags = TFOS_TOP | TFOS_LEFT;
1371 break;
1372
1373 case HTTOPRIGHT:
1374 flags = TFOS_TOP | TFOS_RIGHT;
1375 break;
1376
1377 case HTBOTTOM:
1378 flags = TFOS_BOTTOM;
1379 break;
1380
1381 case HTBOTTOMLEFT:
1382 flags = TFOS_BOTTOM | TFOS_LEFT;
1383 break;
1384
1385 case HTBOTTOMRIGHT:
1386 flags = TFOS_BOTTOM | TFOS_RIGHT;
1387 break;
1388 }
1389 if (flags) FrameTrackFrame(this,flags);
1390 break;
1391 }
1392
1393 case SC_MOVE:
1394 FrameTrackFrame(this,TFOS_MOVE);
1395 break;
1396
1397 case SC_MINIMIZE:
1398 ShowWindow(SW_MINIMIZE);
1399 break;
1400
1401 case SC_MAXIMIZE:
1402 ShowWindow(SW_MAXIMIZE);
1403 break;
1404
1405 case SC_RESTORE:
1406 ShowWindow(SW_RESTORE);
1407 break;
1408
1409 case SC_CLOSE:
1410 return SendInternalMessageA(WM_CLOSE, 0, 0);
1411
1412#if 0
1413 case SC_VSCROLL:
1414 case SC_HSCROLL:
1415 NC_TrackScrollBar( hwnd, wParam, pt32 );
1416 break;
1417
1418 case SC_MOUSEMENU:
1419 MENU_TrackMouseMenuBar( wndPtr, wParam & 0x000F, pt32 );
1420 break;
1421
1422 case SC_KEYMENU:
1423 MENU_TrackKbdMenuBar( wndPtr , wParam , pt.x );
1424 break;
1425
1426 case SC_TASKLIST:
1427 WinExec( "taskman.exe", SW_SHOWNORMAL );
1428 break;
1429
1430 case SC_SCREENSAVE:
1431 if (wParam == SC_ABOUTWINE)
1432 ShellAboutA(hwnd, "Odin", WINE_RELEASE_INFO, 0);
1433 else
1434 if (wParam == SC_PUTMARK)
1435 dprintf(("Mark requested by user\n"));
1436 break;
1437
1438 case SC_HOTKEY:
1439 case SC_ARRANGE:
1440 case SC_NEXTWINDOW:
1441 case SC_PREVWINDOW:
1442 break;
1443#endif
1444 }
1445 return 0;
1446}
1447//******************************************************************************
1448//******************************************************************************
1449LRESULT Win32BaseWindow::DefWndControlColor(UINT ctlType, HDC hdc)
1450{
1451 //SvL: Set background color to default button color (not window (white))
1452 if(ctlType == CTLCOLOR_BTN)
1453 {
1454 SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
1455 SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
1456 return GetSysColorBrush(COLOR_BTNFACE);
1457 }
1458 //SvL: Set background color to default dialog color if window is dialog
1459 if((ctlType == CTLCOLOR_DLG || ctlType == CTLCOLOR_STATIC) && IsDialog()) {
1460 SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
1461 SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
1462 return GetSysColorBrush(COLOR_BTNFACE);
1463 }
1464
1465 if( ctlType == CTLCOLOR_SCROLLBAR)
1466 {
1467 HBRUSH hb = GetSysColorBrush(COLOR_SCROLLBAR);
1468 COLORREF bk = GetSysColor(COLOR_3DHILIGHT);
1469 SetTextColor( hdc, GetSysColor(COLOR_3DFACE));
1470 SetBkColor( hdc, bk);
1471
1472//TODO?
1473#if 0
1474 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
1475 * we better use 0x55aa bitmap brush to make scrollbar's background
1476 * look different from the window background.
1477 */
1478 if (bk == GetSysColor(COLOR_WINDOW)) {
1479 return CACHE_GetPattern55AABrush();
1480 }
1481#endif
1482 UnrealizeObject( hb );
1483 return (LRESULT)hb;
1484 }
1485
1486 SetTextColor( hdc, GetSysColor(COLOR_WINDOWTEXT));
1487
1488 if ((ctlType == CTLCOLOR_EDIT) || (ctlType == CTLCOLOR_LISTBOX))
1489 {
1490 SetBkColor( hdc, GetSysColor(COLOR_WINDOW) );
1491 }
1492 else
1493 {
1494 SetBkColor( hdc, GetSysColor(COLOR_3DFACE) );
1495 return (LRESULT)GetSysColorBrush(COLOR_3DFACE);
1496 }
1497 return (LRESULT)GetSysColorBrush(COLOR_WINDOW);
1498}
1499//******************************************************************************
1500//******************************************************************************
1501LRESULT Win32BaseWindow::DefWndPrint(HDC hdc,ULONG uFlags)
1502{
1503 /*
1504 * Visibility flag.
1505 */
1506 if ( (uFlags & PRF_CHECKVISIBLE) &&
1507 !IsWindowVisible() )
1508 return 0;
1509
1510 /*
1511 * Unimplemented flags.
1512 */
1513 if ( (uFlags & PRF_CHILDREN) ||
1514 (uFlags & PRF_OWNED) ||
1515 (uFlags & PRF_NONCLIENT) )
1516 {
1517 dprintf(("WM_PRINT message with unsupported flags\n"));
1518 }
1519
1520 /*
1521 * Background
1522 */
1523 if ( uFlags & PRF_ERASEBKGND)
1524 SendInternalMessageA(WM_ERASEBKGND, (WPARAM)hdc, 0);
1525
1526 /*
1527 * Client area
1528 */
1529 if ( uFlags & PRF_CLIENT)
1530 SendInternalMessageA(WM_PRINTCLIENT, (WPARAM)hdc, PRF_CLIENT);
1531
1532
1533 return 0;
1534}
1535//******************************************************************************
1536//******************************************************************************
1537LRESULT Win32BaseWindow::DefWindowProcA(UINT Msg, WPARAM wParam, LPARAM lParam)
1538{
1539 switch(Msg)
1540 {
1541 case WM_CLOSE:
1542 dprintf(("DefWindowProcA: WM_CLOSE %x", getWindowHandle()));
1543 DestroyWindow();
1544 return 0;
1545
1546 case WM_GETTEXTLENGTH:
1547 return wndNameLength;
1548
1549 case WM_GETTEXT:
1550 if (!lParam || !wParam) return 0;
1551 if (!windowNameA) ((LPSTR)lParam)[0] = 0;
1552 else lstrcpynA((LPSTR)lParam, windowNameA, wParam);
1553 return min(wndNameLength, wParam);
1554
1555 case WM_SETTEXT:
1556 {
1557 LPCSTR lpsz = (LPCSTR)lParam;
1558
1559 if(windowNameA) free(windowNameA);
1560 if(windowNameW) free(windowNameW);
1561
1562 if (lParam)
1563 {
1564 wndNameLength = strlen(lpsz);
1565 windowNameA = (LPSTR)_smalloc(wndNameLength+1);
1566 strcpy(windowNameA, lpsz);
1567 windowNameW = (LPWSTR)_smalloc((wndNameLength+1)*sizeof(WCHAR));
1568 lstrcpyAtoW(windowNameW, windowNameA);
1569 }
1570 else
1571 {
1572 windowNameA = NULL;
1573 windowNameW = NULL;
1574 wndNameLength = 0;
1575 }
1576 dprintf(("WM_SETTEXT of %x to %s\n", Win32Hwnd, lParam));
1577
1578 if(OS2HwndFrame && (dwStyle & WS_CAPTION) == WS_CAPTION)
1579 return OSLibWinSetWindowText(OS2HwndFrame,(LPSTR)windowNameA);
1580
1581 return TRUE;
1582 }
1583
1584 case WM_SETREDRAW:
1585 {
1586 if (wParam)
1587 {
1588 setStyle(getStyle() | WS_VISIBLE);
1589 OSLibWinEnableWindowUpdate(OS2HwndFrame,TRUE);
1590 } else
1591 {
1592 if (getStyle() & WS_VISIBLE)
1593 {
1594 setStyle(getStyle() & ~WS_VISIBLE);
1595 OSLibWinEnableWindowUpdate(OS2HwndFrame,FALSE);
1596 }
1597 }
1598 return 0;
1599 }
1600
1601 case WM_NCPAINT:
1602 return 0;
1603
1604 case WM_NCACTIVATE:
1605 return TRUE;
1606
1607 case WM_NCCREATE:
1608 return(TRUE);
1609
1610 case WM_NCDESTROY:
1611 return 0;
1612
1613 case WM_NCCALCSIZE:
1614 return NCHandleCalcSize(wParam, (NCCALCSIZE_PARAMS *)lParam);
1615
1616 case WM_CTLCOLORMSGBOX:
1617 case WM_CTLCOLOREDIT:
1618 case WM_CTLCOLORLISTBOX:
1619 case WM_CTLCOLORBTN:
1620 case WM_CTLCOLORDLG:
1621 case WM_CTLCOLORSTATIC:
1622 case WM_CTLCOLORSCROLLBAR:
1623 return DefWndControlColor(Msg - WM_CTLCOLORMSGBOX, (HDC)wParam);
1624
1625 case WM_CTLCOLOR:
1626 return DefWndControlColor(HIWORD(lParam), (HDC)wParam);
1627
1628 case WM_VKEYTOITEM:
1629 case WM_CHARTOITEM:
1630 return -1;
1631
1632 case WM_PARENTNOTIFY:
1633 return 0;
1634
1635 case WM_MOUSEACTIVATE:
1636 {
1637 dprintf(("DefWndProc: WM_MOUSEACTIVATE for %x Msg %s", Win32Hwnd, GetMsgText(HIWORD(lParam))));
1638 if(getStyle() & WS_CHILD && !(getExStyle() & WS_EX_NOPARENTNOTIFY) )
1639 {
1640 if(getParent()) {
1641 LRESULT rc = getParent()->SendInternalMessageA(WM_MOUSEACTIVATE, wParam, lParam );
1642 if(rc) return rc;
1643 }
1644 }
1645 return (LOWORD(lParam) == HTCAPTION) ? MA_NOACTIVATE : MA_ACTIVATE;
1646 }
1647
1648 case WM_ACTIVATE:
1649 //CB: todo
1650 return 0;
1651
1652 case WM_SETCURSOR:
1653 {
1654 dprintf(("DefWndProc: WM_SETCURSOR for %x Msg %s", Win32Hwnd, GetMsgText(HIWORD(lParam))));
1655 if(getStyle() & WS_CHILD && !(getExStyle() & WS_EX_NOPARENTNOTIFY) )
1656 {
1657 if(getParent()) {
1658 LRESULT rc = getParent()->SendInternalMessageA(WM_SETCURSOR, wParam, lParam);
1659 if(rc) return rc;
1660 }
1661 }
1662 if (wParam == Win32Hwnd)
1663 {
1664 HCURSOR hCursor;
1665
1666 switch(lastHitTestVal)
1667 {
1668 case HTLEFT:
1669 case HTRIGHT:
1670 hCursor = LoadCursorA(0,IDC_SIZEWEA);
1671 break;
1672
1673 case HTTOP:
1674 case HTBOTTOM:
1675 hCursor = LoadCursorA(0,IDC_SIZENSA);
1676 break;
1677
1678 case HTTOPLEFT:
1679 case HTBOTTOMRIGHT:
1680 hCursor = LoadCursorA(0,IDC_SIZENWSEA);
1681 break;
1682
1683 case HTTOPRIGHT:
1684 case HTBOTTOMLEFT:
1685 hCursor = LoadCursorA(0,IDC_SIZENESWA);
1686 break;
1687
1688 default:
1689 hCursor = windowClass ? windowClass->getCursor():LoadCursorA(0,IDC_ARROWA);
1690 break;
1691 }
1692
1693 if (hCursor)
1694 {
1695 SetCursor(hCursor);
1696 return 1;
1697 } else return 0;
1698 } else return 0;
1699 }
1700
1701 case WM_MOUSEMOVE:
1702 return 0;
1703
1704 case WM_WINDOWPOSCHANGED:
1705 {
1706
1707/* undocumented SWP flags - from SDK 3.1 */
1708#define SWP_NOCLIENTSIZE 0x0800
1709#define SWP_NOCLIENTMOVE 0x1000
1710
1711 PWINDOWPOS wpos = (PWINDOWPOS)lParam;
1712 WPARAM wp = SIZE_RESTORED;
1713
1714 if (!(wpos->flags & SWP_NOMOVE) && !(wpos->flags & SWP_NOCLIENTMOVE))
1715 SendInternalMessageA(WM_MOVE, 0, MAKELONG(rectClient.left, rectClient.top));
1716
1717 if (!(wpos->flags & SWP_NOSIZE) && !(wpos->flags & SWP_NOCLIENTSIZE))
1718 {
1719 if (dwStyle & WS_MAXIMIZE) wp = SIZE_MAXIMIZED;
1720 else if (dwStyle & WS_MINIMIZE) wp = SIZE_MINIMIZED;
1721
1722 SendInternalMessageA(WM_SIZE, wp, MAKELONG(rectClient.right - rectClient.left,
1723 rectClient.bottom - rectClient.top));
1724 }
1725 return 0;
1726 }
1727 case WM_WINDOWPOSCHANGING:
1728 return HandleWindowPosChanging((WINDOWPOS *)lParam);
1729
1730 case WM_ERASEBKGND:
1731 case WM_ICONERASEBKGND:
1732 {
1733 RECT rect;
1734 int rc;
1735
1736 if (!windowClass || !windowClass->getBackgroundBrush()) return 0;
1737
1738 rc = GetClipBox( (HDC)wParam, &rect );
1739 if ((rc == SIMPLEREGION) || (rc == COMPLEXREGION))
1740 {
1741 HBRUSH hBrush = windowClass->getBackgroundBrush();
1742
1743 if (hBrush <= (HBRUSH)(SYSCOLOR_GetLastColor()+1)) hBrush = GetSysColorBrush(hBrush-1);
1744
1745 FillRect( (HDC)wParam, &rect, hBrush);
1746 }
1747
1748 return 1;
1749 }
1750
1751 case WM_PRINT:
1752 return DefWndPrint(wParam,lParam);
1753
1754 case WM_PAINTICON:
1755 case WM_PAINT:
1756 {
1757 PAINTSTRUCT ps;
1758 HDC hdc = BeginPaint(getWindowHandle(), &ps );
1759 if( hdc )
1760 {
1761 if( (getStyle() & WS_MINIMIZE) && getWindowClass()->getIcon())
1762 {
1763 int x = (rectWindow.right - rectWindow.left - GetSystemMetrics(SM_CXICON))/2;
1764 int y = (rectWindow.bottom - rectWindow.top - GetSystemMetrics(SM_CYICON))/2;
1765 dprintf(("Painting class icon: vis rect=(%i,%i - %i,%i)\n", ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom ));
1766 DrawIcon(hdc, x, y, getWindowClass()->getIcon() );
1767 }
1768 EndPaint(getWindowHandle(), &ps );
1769 }
1770 return 0;
1771 }
1772
1773 case WM_GETDLGCODE:
1774 return 0;
1775
1776 case WM_NCLBUTTONDOWN:
1777 return HandleNCLButtonDown(wParam,lParam);
1778
1779 case WM_NCLBUTTONUP:
1780 return HandleNCLButtonUp(wParam,lParam);
1781
1782 case WM_NCLBUTTONDBLCLK:
1783 return HandleNCLButtonDblClk(wParam,lParam);
1784
1785 case WM_NCRBUTTONDOWN:
1786 case WM_NCRBUTTONDBLCLK:
1787 case WM_NCMBUTTONDOWN:
1788 case WM_NCMBUTTONDBLCLK:
1789 if (lastHitTestVal == HTERROR) MessageBeep(MB_ICONEXCLAMATION);
1790 return 0;
1791
1792 case WM_NCRBUTTONUP:
1793 case WM_NCMBUTTONUP:
1794 return 0;
1795
1796 case WM_NCHITTEST:
1797 {
1798 POINT point;
1799
1800 point.x = (SHORT)LOWORD(lParam);
1801 point.y = (SHORT)HIWORD(lParam);
1802
1803 return FrameHitTest(this,point.x,point.y);
1804 }
1805
1806 case WM_SYSCOMMAND:
1807 {
1808 POINT point;
1809
1810 point.x = LOWORD(lParam);
1811 point.y = HIWORD(lParam);
1812 return HandleSysCommand(wParam, &point);
1813 }
1814
1815 case WM_SYSKEYDOWN:
1816 if(wParam == VK_F4) /* try to close the window */
1817 {
1818 Win32BaseWindow *window = GetTopParent();
1819 if(window && !(window->getClass()->getStyle() & CS_NOCLOSE))
1820 window->PostMessageA(WM_SYSCOMMAND, SC_CLOSE, 0);
1821 }
1822
1823 Win32BaseWindow *siblingWindow;
1824 HWND sibling;
1825 char nameBuffer [40], mnemonic;
1826 int nameLength;
1827
1828 GetWindowTextA (nameBuffer, 40);
1829
1830 // search all sibling to see it this key is their mnemonic
1831 sibling = GetWindow (GW_HWNDFIRST);
1832 while (sibling != 0) {
1833 siblingWindow = GetWindowFromHandle (sibling);
1834 nameLength = siblingWindow->GetWindowTextA (nameBuffer, 40);
1835
1836 // find the siblings mnemonic
1837 mnemonic = '\0';
1838 for (int i=0 ; i<nameLength ; i++) {
1839 if (nameBuffer [i] == '&') {
1840 mnemonic = nameBuffer [i+1];
1841 if ((mnemonic >= 'a') && (mnemonic <= 'z'))
1842 mnemonic -= 32; // make it uppercase
1843 break; // stop searching
1844 }
1845 }
1846
1847 // key matches siblings mnemonic, send mouseclick
1848 if (mnemonic == (char) wParam) {
1849 siblingWindow->SendInternalMessageA (BM_CLICK, 0, 0);
1850 }
1851
1852 sibling = siblingWindow->GetNextWindow (GW_HWNDNEXT);
1853 }
1854
1855 return 0;
1856
1857 case WM_SHOWWINDOW:
1858 if (!lParam) return 0; /* sent from ShowWindow */
1859 if (!(dwStyle & WS_POPUP) || !owner) return 0;
1860 if ((dwStyle & WS_VISIBLE) && wParam) return 0;
1861 else if (!(dwStyle & WS_VISIBLE) && !wParam) return 0;
1862 ShowWindow(wParam ? SW_SHOWNOACTIVATE : SW_HIDE);
1863 return 0;
1864
1865 case WM_CANCELMODE:
1866 //if (getParent() == windowDesktop) EndMenu();
1867 if (GetCapture() == Win32Hwnd) ReleaseCapture();
1868 return 0;
1869
1870 case WM_DROPOBJECT:
1871 return DRAG_FILE;
1872
1873 case WM_QUERYDROPOBJECT:
1874 if (dwExStyle & WS_EX_ACCEPTFILES) return 1;
1875 return 0;
1876
1877 case WM_QUERYDRAGICON:
1878 {
1879 HICON hIcon = windowClass->getCursor();
1880 UINT len;
1881
1882 if(hIcon) return (LRESULT)hIcon;
1883 for(len = 1; len < 64; len++)
1884 {
1885 hIcon = LoadIconA(hInstance,MAKEINTRESOURCEA(len));
1886 if(hIcon)
1887 return (LRESULT)hIcon;
1888 }
1889 return (LRESULT)LoadIconA(0,IDI_APPLICATIONA);
1890 }
1891
1892 case WM_QUERYOPEN:
1893 case WM_QUERYENDSESSION:
1894 return 1;
1895
1896 case WM_NOTIFYFORMAT:
1897 if (IsWindowUnicode()) return NFR_UNICODE;
1898 else return NFR_ANSI;
1899
1900 case WM_SETICON:
1901 case WM_GETICON:
1902 {
1903 LRESULT result = 0;
1904 if (!windowClass) return result;
1905 int index = GCL_HICON;
1906
1907 if (wParam == ICON_SMALL)
1908 index = GCL_HICONSM;
1909
1910 result = windowClass->getClassLongA(index);
1911
1912 if (Msg == WM_SETICON)
1913 windowClass->setClassLongA(index, lParam);
1914
1915 return result;
1916 }
1917
1918 case WM_NOTIFY:
1919 return 0; //comctl32 controls expect this
1920
1921 default:
1922 if(Msg > WM_USER) {
1923 return 0;
1924 }
1925 return 1; //CB: shouldn't this be 0?
1926 }
1927}
1928//******************************************************************************
1929//******************************************************************************
1930LRESULT Win32BaseWindow::DefWindowProcW(UINT Msg, WPARAM wParam, LPARAM lParam)
1931{
1932 switch(Msg)
1933 {
1934 case WM_GETTEXTLENGTH:
1935 return wndNameLength;
1936
1937 case WM_GETTEXT:
1938 if (!lParam || !wParam) return 0;
1939 if (!windowNameW) ((LPWSTR)lParam)[0] = 0;
1940 else lstrcpynW((LPWSTR)lParam,windowNameW,wParam);
1941 return min(wndNameLength,wParam);
1942
1943 case WM_SETTEXT:
1944 {
1945 LPWSTR lpsz = (LPWSTR)lParam;
1946
1947 if(windowNameA) free(windowNameA);
1948 if(windowNameW) free(windowNameW);
1949
1950 if (lParam)
1951 {
1952 wndNameLength = lstrlenW(lpsz);
1953 windowNameA = (LPSTR)_smalloc(wndNameLength+1);
1954 lstrcpyWtoA(windowNameA,lpsz);
1955 windowNameW = (LPWSTR)_smalloc((wndNameLength+1)*sizeof(WCHAR));
1956 lstrcpyW(windowNameW,lpsz);
1957 }
1958 else
1959 {
1960 windowNameA = NULL;
1961 windowNameW = NULL;
1962 wndNameLength = 0;
1963 }
1964
1965 if(OS2HwndFrame && (dwStyle & WS_CAPTION) == WS_CAPTION)
1966 return OSLibWinSetWindowText(OS2HwndFrame,(LPSTR)windowNameA);
1967
1968 return TRUE;
1969 }
1970
1971 default:
1972 return DefWindowProcA(Msg, wParam, lParam);
1973 }
1974}
1975//******************************************************************************
1976//******************************************************************************
1977LRESULT Win32BaseWindow::SendMessageA(ULONG Msg, WPARAM wParam, LPARAM lParam)
1978{
1979 POSTMSG_PACKET *packet;
1980
1981 //if the destination window is created by this process & thread, call window proc directly
1982 if(dwProcessId == currentProcessId && dwThreadId == GetCurrentThreadId()) {
1983 return SendInternalMessageA(Msg, wParam, lParam);
1984 }
1985 //otherwise use WinSendMsg to send it to the right process/thread
1986 packet = (POSTMSG_PACKET *)_smalloc(sizeof(POSTMSG_PACKET));
1987 packet->Msg = Msg;
1988 packet->wParam = wParam;
1989 packet->lParam = lParam;
1990 packet->fUnicode = FALSE;
1991 return OSLibSendMessage(getOS2WindowHandle(), WIN32APP_POSTMSG, WIN32PM_MAGIC, (DWORD)packet);
1992}
1993//******************************************************************************
1994//******************************************************************************
1995LRESULT Win32BaseWindow::SendMessageW(ULONG Msg, WPARAM wParam, LPARAM lParam)
1996{
1997 POSTMSG_PACKET *packet;
1998
1999 //if the destination window is created by this process & thread, call window proc directly
2000 if(dwProcessId == currentProcessId && dwThreadId == GetCurrentThreadId()) {
2001 return SendInternalMessageW(Msg, wParam, lParam);
2002 }
2003 //otherwise use WinSendMsg to send it to the right process/thread
2004 packet = (POSTMSG_PACKET *)_smalloc(sizeof(POSTMSG_PACKET));
2005 packet->Msg = Msg;
2006 packet->wParam = wParam;
2007 packet->lParam = lParam;
2008 packet->fUnicode = TRUE;
2009 return OSLibSendMessage(getOS2WindowHandle(), WIN32APP_POSTMSG, WIN32PM_MAGIC, (DWORD)packet);
2010}
2011//******************************************************************************
2012//Called as a result of an OS/2 message or called from a class method
2013//******************************************************************************
2014LRESULT Win32BaseWindow::SendInternalMessageA(ULONG Msg, WPARAM wParam, LPARAM lParam)
2015{
2016 LRESULT rc;
2017 BOOL fInternalMsgBackup = fInternalMsg;
2018
2019 DebugPrintMessage(getWindowHandle(), Msg, wParam, lParam, FALSE, TRUE);
2020
2021 CallWindowHookProc(WH_CALLWNDPROC, Msg, wParam, lParam, FALSE);
2022
2023 fInternalMsg = TRUE;
2024 switch(Msg)
2025 {
2026 case WM_CREATE:
2027 {
2028 if(CallWindowProcA(win32wndproc, getWindowHandle(), WM_CREATE, 0, lParam) == -1) {
2029 dprintf(("WM_CREATE returned -1\n"));
2030 rc = -1; //don't create window
2031 break;
2032 }
2033 rc = 0;
2034 break;
2035 }
2036 case WM_LBUTTONDOWN:
2037 case WM_MBUTTONDOWN:
2038 case WM_RBUTTONDOWN:
2039 {
2040 if (getParent())
2041 {
2042 POINTS pt = MAKEPOINTS(lParam);
2043 POINT point;
2044
2045 point.x = pt.x;
2046 point.y = pt.y;
2047 MapWindowPoints(Win32Hwnd,getParent()->getWindowHandle(),&point,1);
2048 NotifyParent(Msg,wParam,MAKELPARAM(point.x,point.y));
2049 }
2050 rc = win32wndproc(getWindowHandle(), Msg, wParam, lParam);
2051 break;
2052 }
2053
2054 case WM_DESTROY:
2055 rc = win32wndproc(getWindowHandle(), WM_DESTROY, 0, 0);
2056 break;
2057
2058 default:
2059 rc = CallWindowProcA(win32wndproc, getWindowHandle(), Msg, wParam, lParam);
2060 break;
2061 }
2062 fInternalMsg = fInternalMsgBackup;
2063 return rc;
2064}
2065//******************************************************************************
2066//Called as a result of an OS/2 message or called from a class method
2067//******************************************************************************
2068LRESULT Win32BaseWindow::SendInternalMessageW(ULONG Msg, WPARAM wParam, LPARAM lParam)
2069{
2070 LRESULT rc;
2071 BOOL fInternalMsgBackup = fInternalMsg;
2072
2073 DebugPrintMessage(getWindowHandle(), Msg, wParam, lParam, TRUE, TRUE);
2074
2075 CallWindowHookProc(WH_CALLWNDPROC, Msg, wParam, lParam, TRUE);
2076
2077 fInternalMsg = TRUE;
2078 switch(Msg)
2079 {
2080 case WM_CREATE:
2081 {
2082 if(CallWindowProcW(win32wndproc, getWindowHandle(), WM_CREATE, 0, lParam) == -1) {
2083 dprintf(("WM_CREATE returned -1\n"));
2084 rc = -1; //don't create window
2085 break;
2086 }
2087 rc = 0;
2088 break;
2089 }
2090 case WM_LBUTTONDOWN:
2091 case WM_MBUTTONDOWN:
2092 case WM_RBUTTONDOWN:
2093 NotifyParent(Msg, wParam, lParam);
2094 rc = win32wndproc(getWindowHandle(), Msg, wParam, lParam);
2095 break;
2096
2097 case WM_DESTROY:
2098 rc = win32wndproc(getWindowHandle(), WM_DESTROY, 0, 0);
2099 break;
2100 default:
2101 rc = CallWindowProcW(win32wndproc, getWindowHandle(), Msg, wParam, lParam);
2102 break;
2103 }
2104 fInternalMsg = fInternalMsgBackup;
2105 return rc;
2106}
2107//******************************************************************************
2108//******************************************************************************
2109void Win32BaseWindow::CallWindowHookProc(ULONG hooktype, ULONG Msg, WPARAM wParam, LPARAM lParam, BOOL fUnicode)
2110{
2111 CWPSTRUCT cwp;
2112
2113 cwp.lParam = lParam;
2114 cwp.wParam = wParam;
2115 cwp.message = Msg;
2116 cwp.hwnd = getWindowHandle();
2117
2118 switch(hooktype) {
2119 case WH_CALLWNDPROC:
2120 if(fUnicode) {
2121 HOOK_CallHooksW(WH_CALLWNDPROC, HC_ACTION, 1, (LPARAM)&cwp);
2122 }
2123 else HOOK_CallHooksA(WH_CALLWNDPROC, HC_ACTION, 1, (LPARAM)&cwp);
2124 break;
2125 }
2126}
2127//******************************************************************************
2128//******************************************************************************
2129BOOL Win32BaseWindow::PostMessageA(ULONG msg, WPARAM wParam, LPARAM lParam)
2130{
2131 POSTMSG_PACKET *packet = (POSTMSG_PACKET *)_smalloc(sizeof(POSTMSG_PACKET));
2132
2133 packet->Msg = msg;
2134 packet->wParam = wParam;
2135 packet->lParam = lParam;
2136 packet->fUnicode = FALSE;
2137 return OSLibPostMessage(OS2Hwnd, WIN32APP_POSTMSG, WIN32PM_MAGIC, (DWORD)packet);
2138}
2139//******************************************************************************
2140//******************************************************************************
2141BOOL Win32BaseWindow::PostMessageW(ULONG msg, WPARAM wParam, LPARAM lParam)
2142{
2143 POSTMSG_PACKET *packet = (POSTMSG_PACKET *)_smalloc(sizeof(POSTMSG_PACKET));
2144
2145 packet->Msg = msg;
2146 packet->wParam = wParam;
2147 packet->lParam = lParam;
2148 packet->fUnicode = TRUE;
2149 return OSLibPostMessage(OS2Hwnd, WIN32APP_POSTMSG, WIN32PM_MAGIC, (DWORD)packet);
2150}
2151//******************************************************************************
2152//******************************************************************************
2153BOOL Win32BaseWindow::PostThreadMessageA(ULONG threadid, UINT msg, WPARAM wParam, LPARAM lParam)
2154{
2155 POSTMSG_PACKET *packet = (POSTMSG_PACKET *)_smalloc(sizeof(POSTMSG_PACKET));
2156
2157 dprintf(("PostThreadMessageA %x %x %x %x", threadid, msg, wParam, lParam));
2158 packet->Msg = msg;
2159 packet->wParam = wParam;
2160 packet->lParam = lParam;
2161 packet->fUnicode = FALSE;
2162 return OSLibPostThreadMessage(threadid, WIN32APP_POSTMSG, WIN32PM_MAGIC, (LPARAM)packet);
2163}
2164//******************************************************************************
2165//******************************************************************************
2166BOOL Win32BaseWindow::PostThreadMessageW(ULONG threadid, UINT msg, WPARAM wParam, LPARAM lParam)
2167{
2168 POSTMSG_PACKET *packet = (POSTMSG_PACKET *)_smalloc(sizeof(POSTMSG_PACKET));
2169
2170 dprintf(("PostThreadMessageW %x %x %x %x", threadid, msg, wParam, lParam));
2171 packet->Msg = msg;
2172 packet->wParam = wParam;
2173 packet->lParam = lParam;
2174 packet->fUnicode = TRUE;
2175 return OSLibPostThreadMessage(threadid, WIN32APP_POSTMSG, WIN32PM_MAGIC, (LPARAM)packet);
2176}
2177//******************************************************************************
2178//******************************************************************************
2179ULONG Win32BaseWindow::PostMessage(POSTMSG_PACKET *packet)
2180{
2181 ULONG rc;
2182
2183 if(packet == NULL)
2184 return 0;
2185
2186 if(packet->fUnicode) {
2187 rc = SendInternalMessageW(packet->Msg, packet->wParam, packet->lParam);
2188 }
2189 else rc = SendInternalMessageA(packet->Msg, packet->wParam, packet->lParam);
2190
2191 free(packet);
2192 return rc;
2193}
2194//******************************************************************************
2195//TODO: Do this more efficiently
2196//******************************************************************************
2197LRESULT Win32BaseWindow::BroadcastMessageA(int type, UINT msg, WPARAM wParam, LPARAM lParam)
2198{
2199 Win32BaseWindow *window;
2200 HWND hwnd = WNDHANDLE_MAGIC_HIGHWORD;
2201
2202 dprintf(("BroadCastMessageA %x %x %x", msg, wParam, lParam, GetFS()));
2203
2204 for(int i=0;i<MAX_WINDOW_HANDLES;i++) {
2205 window = GetWindowFromHandle(hwnd++);
2206 if(window) {
2207 if ((window->getStyle() & WS_POPUP) || ((window->getStyle() & WS_CAPTION) == WS_CAPTION))
2208 {
2209
2210 if(type == BROADCAST_SEND) {
2211 window->SendInternalMessageA(msg, wParam, lParam);
2212 }
2213 else window->PostMessageA(msg, wParam, lParam);
2214 }
2215 }
2216 }
2217 return 0;
2218}
2219//******************************************************************************
2220//TODO: Do this more efficiently
2221//******************************************************************************
2222LRESULT Win32BaseWindow::BroadcastMessageW(int type, UINT msg, WPARAM wParam, LPARAM lParam)
2223{
2224 Win32BaseWindow *window;
2225 HWND hwnd = WNDHANDLE_MAGIC_HIGHWORD;
2226
2227
2228 dprintf(("BroadCastMessageW %x %x %x", msg, wParam, lParam));
2229
2230 for(int i=0;i<MAX_WINDOW_HANDLES;i++) {
2231 window = GetWindowFromHandle(hwnd++);
2232 if(window) {
2233 if ((window->getStyle() & WS_POPUP) || ((window->getStyle() & WS_CAPTION) == WS_CAPTION))
2234 {
2235
2236 if(type == BROADCAST_SEND) {
2237 window->SendInternalMessageW(msg, wParam, lParam);
2238 }
2239 else window->PostMessageW(msg, wParam, lParam);
2240 }
2241 }
2242 }
2243 return 0;
2244}
2245//******************************************************************************
2246//******************************************************************************
2247void Win32BaseWindow::NotifyParent(UINT Msg, WPARAM wParam, LPARAM lParam)
2248{
2249 Win32BaseWindow *window = this;
2250 Win32BaseWindow *parentwindow;
2251
2252 while(window)
2253 {
2254 if(window->getStyle() & WS_CHILD && !(window->getExStyle() & WS_EX_NOPARENTNOTIFY) )
2255 {
2256 /* Notify the parent window only */
2257 parentwindow = window->getParent();
2258 if(parentwindow) {
2259 parentwindow->SendInternalMessageA(WM_PARENTNOTIFY, MAKEWPARAM(Msg, getWindowId()), lParam );
2260 }
2261 }
2262 else break;
2263
2264 window = parentwindow;
2265 }
2266}
2267//******************************************************************************
2268//******************************************************************************
2269BOOL Win32BaseWindow::SetMenu(HMENU hMenu)
2270{
2271
2272 dprintf(("SetMenu %x", hMenu));
2273 OS2HwndMenu = OSLibWinSetMenu(OS2HwndFrame, hMenu);
2274 if(OS2HwndMenu == 0) {
2275 dprintf(("Win32BaseWindow::SetMenu OS2HwndMenu == 0"));
2276 return FALSE;
2277 }
2278 return TRUE;
2279}
2280//******************************************************************************
2281//******************************************************************************
2282BOOL Win32BaseWindow::SetAccelTable(HACCEL hAccel)
2283{
2284 Win32Resource *winres = (Win32Resource *)hAccel;
2285 HANDLE accelhandle;
2286
2287 if(HIWORD(hAccel) == 0) {
2288 dprintf(("SetAccelTable: hAccel %x invalid", hAccel));
2289 SetLastError(ERROR_INVALID_PARAMETER);
2290 return FALSE;
2291 }
2292 acceltableResource = winres;
2293 accelhandle = OSLibWinSetAccelTable(OS2HwndFrame, winres->getOS2Handle(), winres->lockOS2Resource());
2294 winres->setOS2Handle(accelhandle);
2295 return(accelhandle != 0);
2296}
2297//******************************************************************************
2298//******************************************************************************
2299BOOL Win32BaseWindow::SetIcon(HICON hIcon)
2300{
2301 dprintf(("Win32BaseWindow::SetIcon %x", hIcon));
2302 if(OSLibWinSetIcon(OS2HwndFrame, hIcon) == TRUE) {
2303//TODO: Wine does't send these. Correct?
2304// SendInternalMessageA(WM_SETICON, ICON_BIG, hIcon);
2305 return TRUE;
2306 }
2307 return FALSE;
2308}
2309//******************************************************************************
2310//******************************************************************************
2311BOOL Win32BaseWindow::ShowWindow(ULONG nCmdShow)
2312{
2313 ULONG showstate = 0;
2314 HWND hWinAfter;
2315
2316 dprintf(("ShowWindow %x %x", getWindowHandle(), nCmdShow));
2317#if 1
2318 if (flags & WIN_NEED_SIZE)
2319 {
2320 /* should happen only in CreateWindowEx() */
2321 int wParam = SIZE_RESTORED;
2322
2323 flags &= ~WIN_NEED_SIZE;
2324 if (dwStyle & WS_MAXIMIZE)
2325 wParam = SIZE_MAXIMIZED;
2326 else
2327 if (dwStyle & WS_MINIMIZE)
2328 wParam = SIZE_MINIMIZED;
2329
2330 SendInternalMessageA(WM_SIZE, wParam,
2331 MAKELONG(rectClient.right-rectClient.left,
2332 rectClient.bottom-rectClient.top));
2333 SendInternalMessageA(WM_MOVE, 0, MAKELONG( rectClient.left, rectClient.top ) );
2334 }
2335#else
2336 if(fFirstShow) {
2337 if(isFrameWindow() && IS_OVERLAPPED(getStyle()) && !isChild()) {
2338 SendInternalMessageA(WM_SIZE, SIZE_RESTORED,
2339 MAKELONG(rectClient.right-rectClient.left,
2340 rectClient.bottom-rectClient.top));
2341 SendInternalMessageA(WM_MOVE, 0, MAKELONG( rectClient.left, rectClient.top ) );
2342
2343 }
2344 fFirstShow = FALSE;
2345 }
2346#endif
2347 switch(nCmdShow)
2348 {
2349 case SW_SHOW:
2350 case SW_SHOWDEFAULT: //todo
2351 showstate = SWPOS_SHOW | SWPOS_ACTIVATE;
2352 break;
2353 case SW_HIDE:
2354 showstate = SWPOS_HIDE;
2355 break;
2356 case SW_RESTORE:
2357 showstate = SWPOS_RESTORE | SWPOS_SHOW | SWPOS_ACTIVATE;
2358 break;
2359 case SW_MINIMIZE:
2360 showstate = SWPOS_MINIMIZE;
2361 break;
2362 case SW_SHOWMAXIMIZED:
2363 showstate = SWPOS_MAXIMIZE | SWPOS_SHOW | SWPOS_ACTIVATE;
2364 break;
2365 case SW_SHOWMINIMIZED:
2366 showstate = SWPOS_MINIMIZE | SWPOS_SHOW | SWPOS_ACTIVATE;
2367 break;
2368 case SW_SHOWMINNOACTIVE:
2369 showstate = SWPOS_MINIMIZE | SWPOS_SHOW;
2370 break;
2371 case SW_SHOWNA:
2372 showstate = SWPOS_SHOW;
2373 break;
2374 case SW_SHOWNOACTIVATE:
2375 showstate = SWPOS_SHOW;
2376 break;
2377 case SW_SHOWNORMAL:
2378 showstate = SWPOS_RESTORE | SWPOS_ACTIVATE | SWPOS_SHOW;
2379 break;
2380 }
2381
2382 /* We can't activate a child window (WINE) */
2383 if(getStyle() & WS_CHILD)
2384 showstate &= ~SWPOS_ACTIVATE;
2385
2386 if(showstate & SWPOS_SHOW) {
2387 setStyle(getStyle() | WS_VISIBLE);
2388 }
2389 else setStyle(getStyle() & ~WS_VISIBLE);
2390
2391 BOOL rc = OSLibWinShowWindow(OS2HwndFrame, showstate);
2392
2393 return rc;
2394}
2395//******************************************************************************
2396//******************************************************************************
2397BOOL Win32BaseWindow::SetWindowPos(HWND hwndInsertAfter, int x, int y, int cx, int cy, UINT fuFlags)
2398{
2399 BOOL rc = FALSE;
2400 Win32BaseWindow *window;
2401 HWND hParent = 0;
2402
2403 dprintf (("SetWindowPos %x %x (%d,%d)(%d,%d) %x", Win32Hwnd, hwndInsertAfter, x, y, cx, cy, fuFlags));
2404
2405 if (fuFlags &
2406 ~(SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER |
2407 SWP_NOREDRAW | SWP_NOACTIVATE | SWP_FRAMECHANGED |
2408 SWP_SHOWWINDOW | SWP_HIDEWINDOW | SWP_NOCOPYBITS |
2409 SWP_NOOWNERZORDER))
2410 {
2411 return FALSE;
2412 }
2413
2414 WINDOWPOS wpos;
2415 SWP swp, swpOld;
2416
2417 wpos.flags = fuFlags;
2418 wpos.cy = cy;
2419 wpos.cx = cx;
2420 wpos.x = x;
2421 wpos.y = y;
2422 wpos.hwndInsertAfter = hwndInsertAfter;
2423 wpos.hwnd = getWindowHandle();
2424
2425 if(~fuFlags & (SWP_NOMOVE | SWP_NOSIZE))
2426 {
2427 if (isChild())
2428 {
2429 Win32BaseWindow *windowParent = getParent();
2430 if(windowParent) {
2431 hParent = getParent()->getOS2WindowHandle();
2432 }
2433 else dprintf(("WARNING: Win32BaseWindow::SetWindowPos window %x is child but has no parent!!", getWindowHandle()));
2434 }
2435 OSLibWinQueryWindowPos(OS2HwndFrame, &swpOld);
2436 }
2437
2438 OSLibMapWINDOWPOStoSWP(&wpos, &swp, &swpOld, hParent, OS2HwndFrame);
2439 if (swp.fl == 0)
2440 return TRUE;
2441
2442// if ((swp.fl & SWPOS_ZORDER) && (swp.hwndInsertBehind > HWNDOS_BOTTOM))
2443 if ((swp.hwndInsertBehind > HWNDOS_BOTTOM))
2444 {
2445 Win32BaseWindow *wndBehind = Win32BaseWindow::GetWindowFromHandle(swp.hwndInsertBehind);
2446 if(wndBehind) {
2447 swp.hwndInsertBehind = wndBehind->getOS2FrameWindowHandle();
2448 }
2449 else {
2450 dprintf(("ERROR: SetWindowPos: hwndInsertBehind %x invalid!",swp.hwndInsertBehind));
2451 swp.hwndInsertBehind = 0;
2452 }
2453 }
2454#if 0
2455 if (isFrameWindow())
2456 {
2457 if (!isChild())
2458 {
2459 POINT maxSize, maxPos, minTrack, maxTrack;
2460
2461 GetMinMaxInfo(&maxSize, &maxPos, &minTrack, &maxTrack);
2462
2463 if (swp.cx > maxTrack.x) swp.cx = maxTrack.x;
2464 if (swp.cy > maxTrack.y) swp.cy = maxTrack.y;
2465 if (swp.cx < minTrack.x) swp.cx = minTrack.x;
2466 if (swp.cy < minTrack.y) swp.cy = minTrack.y;
2467 }
2468 swp.hwnd = OS2HwndFrame;
2469 }
2470 else
2471#endif
2472 swp.hwnd = OS2HwndFrame;
2473
2474 dprintf (("WinSetWindowPos %x %x (%d,%d)(%d,%d) %x", swp.hwnd, swp.hwndInsertBehind, swp.x, swp.y, swp.cx, swp.cy, swp.fl));
2475
2476 rc = OSLibWinSetMultWindowPos(&swp, 1);
2477
2478 if (rc == FALSE)
2479 {
2480 dprintf(("OSLibWinSetMultWindowPos failed! Error %x",OSLibWinGetLastError()));
2481 }
2482
2483 //SWP_FRAMECHANGED is ignored, not necessary for OS/2
2484
2485 return (rc);
2486}
2487//******************************************************************************
2488//TODO: WPF_RESTOREMAXIMIZED
2489//******************************************************************************
2490BOOL Win32BaseWindow::SetWindowPlacement(WINDOWPLACEMENT *winpos)
2491{
2492 if(isFrameWindow())
2493 {
2494 // Set the minimized position
2495 if (winpos->flags & WPF_SETMINPOSITION)
2496 {
2497 OSLibSetWindowMinPos(OS2HwndFrame, winpos->ptMinPosition.x, winpos->ptMinPosition.y);
2498 }
2499
2500 //TODO: Max position
2501
2502 // Set the new restore position.
2503 OSLibSetWindowRestoreRect(OS2HwndFrame, &winpos->rcNormalPosition);
2504 }
2505
2506 return ShowWindow(winpos->showCmd);
2507}
2508//******************************************************************************
2509//Also destroys all the child windows (destroy children first, parent last)
2510//******************************************************************************
2511BOOL Win32BaseWindow::DestroyWindow()
2512{
2513 /* Call hooks */
2514 if(HOOK_CallHooksA( WH_CBT, HCBT_DESTROYWND, getWindowHandle(), 0L))
2515 {
2516 return FALSE;
2517 }
2518
2519 if(!(getStyle() & WS_CHILD) && getOwner() == NULL)
2520 {
2521 HOOK_CallHooksA(WH_SHELL, HSHELL_WINDOWDESTROYED, getWindowHandle(), 0L);
2522 /* FIXME: clean up palette - see "Internals" p.352 */
2523 }
2524
2525 if((getStyle() & WS_CHILD) && !(getExStyle() & WS_EX_NOPARENTNOTIFY))
2526 {
2527 if(getParent())
2528 {
2529 /* Notify the parent window only */
2530 getParent()->SendMessageA(WM_PARENTNOTIFY, MAKEWPARAM(WM_DESTROY, getWindowId()), (LPARAM)getWindowHandle());
2531 if( !::IsWindow(getWindowHandle()) )
2532 {
2533 return TRUE;
2534 }
2535 }
2536 else DebugInt3();
2537 }
2538 fDestroyWindowCalled = TRUE;
2539 return OSLibWinDestroyWindow(OS2HwndFrame);
2540}
2541//******************************************************************************
2542//******************************************************************************
2543Win32BaseWindow *Win32BaseWindow::getParent()
2544{
2545 Win32BaseWindow *wndparent = (Win32BaseWindow *)ChildWindow::GetParent();
2546 return ((ULONG)wndparent == (ULONG)windowDesktop) ? NULL : wndparent;
2547}
2548//******************************************************************************
2549//******************************************************************************
2550HWND Win32BaseWindow::GetParent()
2551{
2552 Win32BaseWindow *wndparent;
2553
2554 if ((!(getStyle() & (WS_POPUP|WS_CHILD))))
2555 {
2556 return 0;
2557 }
2558 wndparent = ((getStyle() & WS_CHILD) ? getParent() : getOwner());
2559
2560 return (wndparent) ? wndparent->getWindowHandle() : 0;
2561}
2562//******************************************************************************
2563//******************************************************************************
2564HWND Win32BaseWindow::SetParent(HWND hwndNewParent)
2565{
2566 HWND oldhwnd;
2567 Win32BaseWindow *newparent;
2568
2569 if(getParent()) {
2570 oldhwnd = getParent()->getWindowHandle();
2571 getParent()->RemoveChild(this);
2572 }
2573 else oldhwnd = 0;
2574
2575 newparent = GetWindowFromHandle(hwndNewParent);
2576 if(newparent)
2577 {
2578 setParent(newparent);
2579 getParent()->AddChild(this);
2580 OSLibWinSetParent(getOS2FrameWindowHandle(), getParent()->getOS2WindowHandle());
2581 return oldhwnd;
2582 }
2583 else {
2584 setParent(windowDesktop);
2585 windowDesktop->AddChild(this);
2586 OSLibWinSetParent(getOS2FrameWindowHandle(), OSLIB_HWND_DESKTOP);
2587 return oldhwnd;
2588 }
2589}
2590//******************************************************************************
2591//******************************************************************************
2592BOOL Win32BaseWindow::IsChild(HWND hwndParent)
2593{
2594 if(getParent()) {
2595 return getParent()->getWindowHandle() == hwndParent;
2596 }
2597 else return 0;
2598}
2599//******************************************************************************
2600//******************************************************************************
2601HWND Win32BaseWindow::GetTopWindow()
2602{
2603 return GetWindow(GW_CHILD);
2604}
2605//******************************************************************************
2606// Get the top-level parent for a child window.
2607//******************************************************************************
2608Win32BaseWindow *Win32BaseWindow::GetTopParent()
2609{
2610 Win32BaseWindow *window = this;
2611
2612 while(window && (window->getStyle() & WS_CHILD))
2613 {
2614 window = window->getParent();
2615 }
2616 return window;
2617}
2618//******************************************************************************
2619//Don't call WinUpdateWindow as that one also updates the child windows
2620//Also need to send WM_PAINT directly to the window procedure, which doesn't
2621//always happen with WinUpdateWindow (could be posted if thread doesn't own window)
2622//******************************************************************************
2623BOOL Win32BaseWindow::UpdateWindow()
2624{
2625 RECT rect;
2626
2627 if(OSLibWinQueryUpdateRect(OS2Hwnd, &rect))
2628 {//update region not empty
2629 HDC hdc;
2630
2631 hdc = O32_GetDC(OS2Hwnd);
2632 if (isIcon)
2633 {
2634 SendInternalMessageA(WM_ICONERASEBKGND, (WPARAM)hdc, 0);
2635 SendInternalMessageA(WM_PAINTICON, 0, 0);
2636 }
2637 else
2638 {
2639 SendInternalMessageA(WM_ERASEBKGND, (WPARAM)hdc, 0);
2640 SendInternalMessageA(WM_PAINT, 0, 0);
2641 }
2642 O32_ReleaseDC(OS2Hwnd, hdc);
2643 }
2644 return TRUE;
2645}
2646//******************************************************************************
2647//******************************************************************************
2648BOOL Win32BaseWindow::IsIconic()
2649{
2650 return OSLibWinIsIconic(OS2Hwnd);
2651}
2652//******************************************************************************
2653//TODO: Should not enumerate children that are created during the enumeration!
2654//******************************************************************************
2655BOOL Win32BaseWindow::EnumChildWindows(WNDENUMPROC lpfn, LPARAM lParam)
2656{
2657 BOOL rc = TRUE;
2658 HWND hwnd;
2659 Win32BaseWindow *prevchild = 0, *child = 0;
2660
2661 dprintf(("EnumChildWindows of %x parameter %x %x (%x)", getWindowHandle(), lpfn, lParam, getFirstChild()));
2662 for (child = (Win32BaseWindow *)getFirstChild(); child; child = (Win32BaseWindow *)child->getNextChild())
2663 {
2664 dprintf(("EnumChildWindows: enumerating child %x", child->getWindowHandle()));
2665 hwnd = child->getWindowHandle();
2666 if(child->getOwner()) {
2667 continue; //shouldn't have an owner (Wine)
2668 }
2669 if(lpfn(hwnd, lParam) == FALSE)
2670 {
2671 rc = FALSE;
2672 break;
2673 }
2674 //check if the window still exists
2675 if(!::IsWindow(hwnd))
2676 {
2677 child = prevchild;
2678 continue;
2679 }
2680 if(child->getFirstChild() != NULL)
2681 {
2682 dprintf(("EnumChildWindows: Enumerate children of %x", child->getWindowHandle()));
2683 if(child->EnumChildWindows(lpfn, lParam) == FALSE)
2684 {
2685 rc = FALSE;
2686 break;
2687 }
2688 }
2689 prevchild = child;
2690 }
2691 return rc;
2692}
2693//******************************************************************************
2694//Enumerate first-level children only and check thread id
2695//******************************************************************************
2696BOOL Win32BaseWindow::EnumThreadWindows(DWORD dwThreadId, WNDENUMPROC lpfn, LPARAM lParam)
2697{
2698 Win32BaseWindow *child = 0;
2699 ULONG tid, pid;
2700 BOOL rc;
2701 HWND hwnd;
2702
2703 dprintf(("EnumThreadWindows %x %x %x", dwThreadId, lpfn, lParam));
2704
2705 for (child = (Win32BaseWindow *)getFirstChild(); child; child = (Win32BaseWindow *)child->getNextChild())
2706 {
2707 OSLibWinQueryWindowProcess(child->getOS2WindowHandle(), &pid, &tid);
2708
2709 if(dwThreadId == tid) {
2710 dprintf2(("EnumThreadWindows: Found Window %x", child->getWindowHandle()));
2711 if((rc = lpfn(child->getWindowHandle(), lParam)) == FALSE) {
2712 break;
2713 }
2714 }
2715 }
2716 return TRUE;
2717}
2718//******************************************************************************
2719//Enumerate first-level children only
2720//******************************************************************************
2721BOOL Win32BaseWindow::EnumWindows(WNDENUMPROC lpfn, LPARAM lParam)
2722{
2723 Win32BaseWindow *child = 0;
2724 BOOL rc;
2725 HWND hwnd;
2726
2727 dprintf(("EnumWindows %x %x", lpfn, lParam));
2728
2729 for (child = (Win32BaseWindow *)getFirstChild(); child; child = (Win32BaseWindow *)child->getNextChild())
2730 {
2731 hwnd = child->getWindowHandle();
2732
2733 dprintf2(("EnumWindows: Found Window %x", child->getWindowHandle()));
2734 if((rc = lpfn(child->getWindowHandle(), lParam)) == FALSE) {
2735 break;
2736 }
2737 }
2738 return TRUE;
2739}
2740//******************************************************************************
2741//******************************************************************************
2742Win32BaseWindow *Win32BaseWindow::FindWindowById(int id)
2743{
2744 for (Win32BaseWindow *child = (Win32BaseWindow *)getFirstChild(); child; child = (Win32BaseWindow *)child->getNextChild())
2745 {
2746 if (child->getWindowId() == id)
2747 {
2748 return child;
2749 }
2750 }
2751 return 0;
2752}
2753//******************************************************************************
2754//TODO:
2755//We assume (for now) that if hwndParent or hwndChildAfter are real window handles, that
2756//the current process owns them.
2757//******************************************************************************
2758HWND Win32BaseWindow::FindWindowEx(HWND hwndParent, HWND hwndChildAfter, LPSTR lpszClass, LPSTR lpszWindow,
2759 BOOL fUnicode)
2760{
2761 Win32BaseWindow *parent = GetWindowFromHandle(hwndParent);
2762 Win32BaseWindow *child = GetWindowFromHandle(hwndChildAfter);
2763
2764 if((hwndParent != OSLIB_HWND_DESKTOP && !parent) ||
2765 (hwndChildAfter != 0 && !child) ||
2766 (hwndParent == OSLIB_HWND_DESKTOP && hwndChildAfter != 0))
2767 {
2768 dprintf(("Win32BaseWindow::FindWindowEx: parent or child not found %x %x", hwndParent, hwndChildAfter));
2769 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
2770 return 0;
2771 }
2772 if(hwndParent != OSLIB_HWND_DESKTOP)
2773 {//if the current process owns the window, just do a quick search
2774 child = (Win32BaseWindow *)parent->getFirstChild();
2775 if(hwndChildAfter != 0)
2776 {
2777 while(child)
2778 {
2779 if(child->getWindowHandle() == hwndChildAfter)
2780 {
2781 child = (Win32BaseWindow *)child->getNextChild();
2782 break;
2783 }
2784 child = (Win32BaseWindow *)child->getNextChild();
2785 }
2786 }
2787 while(child)
2788 {
2789 if(child->getWindowClass()->hasClassName(lpszClass, fUnicode) &&
2790 (!lpszWindow || child->hasWindowName(lpszWindow, fUnicode)))
2791 {
2792 dprintf(("FindWindowEx: Found window %x", child->getWindowHandle()));
2793 return child->getWindowHandle();
2794 }
2795 child = (Win32BaseWindow *)child->getNextChild();
2796 }
2797 }
2798 else {
2799 Win32BaseWindow *wnd;
2800 HWND henum, hwnd;
2801
2802 henum = OSLibWinBeginEnumWindows(OSLIB_HWND_DESKTOP);
2803 hwnd = OSLibWinGetNextWindow(henum);
2804
2805 while(hwnd)
2806 {
2807 wnd = GetWindowFromOS2Handle(hwnd);
2808 if(wnd == NULL) {
2809 hwnd = OSLibWinQueryClientWindow(hwnd);
2810 if(hwnd) wnd = GetWindowFromOS2Handle(hwnd);
2811 if(!hwnd) wnd = GetWindowFromOS2FrameHandle(hwnd);
2812 }
2813
2814 if(wnd) {
2815 if(wnd->getWindowClass()->hasClassName(lpszClass, fUnicode) &&
2816 (!lpszWindow || wnd->hasWindowName(lpszWindow, fUnicode)))
2817 {
2818 OSLibWinEndEnumWindows(henum);
2819 dprintf(("FindWindowEx: Found window %x", wnd->getWindowHandle()));
2820 return wnd->getWindowHandle();
2821 }
2822 }
2823 hwnd = OSLibWinGetNextWindow(henum);
2824 }
2825 OSLibWinEndEnumWindows(henum);
2826 }
2827 SetLastError(ERROR_CANNOT_FIND_WND_CLASS); //TODO: not always correct
2828 return 0;
2829}
2830//******************************************************************************
2831//******************************************************************************
2832HWND Win32BaseWindow::GetWindow(UINT uCmd)
2833{
2834 HWND hwndRelated = 0;
2835 Win32BaseWindow *window;
2836
2837 switch(uCmd)
2838 {
2839 case GW_HWNDFIRST:
2840 if(getParent()) {
2841 window = (Win32BaseWindow *)getParent()->getFirstChild();
2842 hwndRelated = window->getWindowHandle();
2843 }
2844 break;
2845
2846 case GW_HWNDLAST:
2847 if(!getParent())
2848 {
2849 goto end;
2850 }
2851
2852 window = this;
2853 while(window->getNextChild())
2854 {
2855 window = (Win32BaseWindow *)window->getNextChild();
2856 }
2857 hwndRelated = window->getWindowHandle();
2858 break;
2859
2860 case GW_HWNDNEXT:
2861 window = (Win32BaseWindow *)getNextChild();
2862 if(window) {
2863 hwndRelated = window->getWindowHandle();
2864 }
2865 break;
2866
2867 case GW_HWNDPREV:
2868 if(!getParent())
2869 {
2870 goto end;
2871 }
2872 window = (Win32BaseWindow *)(getParent()->getFirstChild()); /* First sibling */
2873 if(window == this)
2874 {
2875 hwndRelated = 0; /* First in list */
2876 goto end;
2877 }
2878 while(window->getNextChild())
2879 {
2880 if (window->getNextChild() == this)
2881 {
2882 hwndRelated = window->getWindowHandle();
2883 goto end;
2884 }
2885 window = (Win32BaseWindow *)window->getNextChild();
2886 }
2887 break;
2888
2889 case GW_OWNER:
2890 if(getOwner()) {
2891 hwndRelated = getOwner()->getWindowHandle();
2892 }
2893 break;
2894
2895 case GW_CHILD:
2896 if(getFirstChild()) {
2897 hwndRelated = ((Win32BaseWindow *)getFirstChild())->getWindowHandle();
2898 }
2899 break;
2900 }
2901end:
2902 dprintf(("GetWindow %x %d returned %x", getWindowHandle(), uCmd, hwndRelated));
2903 return hwndRelated;
2904}
2905//******************************************************************************
2906//******************************************************************************
2907HWND Win32BaseWindow::SetActiveWindow()
2908{
2909 HWND hwndActive;
2910 Win32BaseWindow *win32wnd;
2911 ULONG magic;
2912
2913 hwndActive = OSLibWinSetActiveWindow(OS2HwndFrame);
2914 win32wnd = (Win32BaseWindow *)OSLibWinGetWindowULong(hwndActive, OFFSET_WIN32WNDPTR);
2915 magic = OSLibWinGetWindowULong(hwndActive, OFFSET_WIN32PM_MAGIC);
2916 if(CheckMagicDword(magic) && win32wnd)
2917 {
2918 return win32wnd->getWindowHandle();
2919 }
2920 return 0;
2921}
2922//******************************************************************************
2923//WM_ENABLE is sent to hwnd, but not to it's children (as it should be)
2924//******************************************************************************
2925BOOL Win32BaseWindow::EnableWindow(BOOL fEnable)
2926{
2927 return OSLibWinEnableWindow(OS2HwndFrame, fEnable);
2928}
2929//******************************************************************************
2930//******************************************************************************
2931BOOL Win32BaseWindow::CloseWindow()
2932{
2933 return OSLibWinMinimizeWindow(OS2HwndFrame);
2934}
2935//******************************************************************************
2936//******************************************************************************
2937HWND Win32BaseWindow::GetActiveWindow()
2938{
2939 HWND hwndActive;
2940 Win32BaseWindow *win32wnd;
2941 ULONG magic;
2942
2943 hwndActive = OSLibWinQueryActiveWindow();
2944
2945 return OS2ToWin32Handle(hwndActive);
2946}
2947//******************************************************************************
2948//******************************************************************************
2949BOOL Win32BaseWindow::IsWindowEnabled()
2950{
2951 return OSLibWinIsWindowEnabled(OS2HwndFrame);
2952}
2953//******************************************************************************
2954//******************************************************************************
2955BOOL Win32BaseWindow::IsWindowVisible()
2956{
2957#if 1
2958 return (dwStyle & WS_VISIBLE) == WS_VISIBLE;
2959#else
2960 return OSLibWinIsWindowVisible(OS2HwndFrame);
2961#endif
2962}
2963//******************************************************************************
2964//******************************************************************************
2965BOOL Win32BaseWindow::GetWindowRect(PRECT pRect)
2966{
2967 return OSLibWinQueryWindowRect(OS2HwndFrame, pRect, RELATIVE_TO_SCREEN);
2968}
2969//******************************************************************************
2970//******************************************************************************
2971BOOL Win32BaseWindow::hasWindowName(LPSTR wndname, BOOL fUnicode)
2972{
2973 if(wndname == NULL)
2974 return FALSE;
2975
2976 if(fUnicode) {
2977 return (lstrcmpW(windowNameW, (LPWSTR)wndname) == 0);
2978 }
2979 else return (strcmp(windowNameA, wndname) == 0);
2980}
2981//******************************************************************************
2982//******************************************************************************
2983int Win32BaseWindow::GetWindowTextLength()
2984{
2985 return SendInternalMessageA(WM_GETTEXTLENGTH,0,0);
2986}
2987//******************************************************************************
2988//******************************************************************************
2989int Win32BaseWindow::GetWindowTextA(LPSTR lpsz, int cch)
2990{
2991 return SendInternalMessageA(WM_GETTEXT,(WPARAM)cch,(LPARAM)lpsz);
2992}
2993//******************************************************************************
2994//******************************************************************************
2995int Win32BaseWindow::GetWindowTextW(LPWSTR lpsz, int cch)
2996{
2997 return SendInternalMessageW(WM_GETTEXT,(WPARAM)cch,(LPARAM)lpsz);
2998}
2999//******************************************************************************
3000//******************************************************************************
3001BOOL Win32BaseWindow::SetWindowTextA(LPSTR lpsz)
3002{
3003 return SendInternalMessageA(WM_SETTEXT,0,(LPARAM)lpsz);
3004}
3005//******************************************************************************
3006//******************************************************************************
3007BOOL Win32BaseWindow::SetWindowTextW(LPWSTR lpsz)
3008{
3009 return SendInternalMessageW(WM_SETTEXT,0,(LPARAM)lpsz);
3010}
3011//******************************************************************************
3012//******************************************************************************
3013VOID Win32BaseWindow::updateWindowStyle(DWORD oldExStyle,DWORD oldStyle)
3014{
3015 if(IsWindowDestroyed()) return;
3016
3017 //CB: todo: dwExStyle, creating new frame controls, destroy not used controls, WS_VISIBLE, WS_CHILD, ...
3018 // write test cases
3019 if ((dwStyle & 0xFFFF0000) != (oldStyle & 0xFFFF0000))
3020 {
3021 //dprintf(("updateWindowStyle: %x %x",oldStyle,dwStyle));
3022 OSLibSetWindowStyle(OS2HwndFrame, dwStyle, fTaskList);
3023 }
3024}
3025//******************************************************************************
3026//******************************************************************************
3027LONG Win32BaseWindow::SetWindowLongA(int index, ULONG value, BOOL fUnicode)
3028{
3029 LONG oldval;
3030
3031 dprintf2(("SetWindowLong%c %x %d %x", (fUnicode) ? 'W' : 'A', getWindowHandle(), index, value));
3032 switch(index) {
3033 case GWL_EXSTYLE:
3034 {
3035 STYLESTRUCT ss;
3036
3037 if(dwExStyle == value)
3038 return value;
3039
3040 ss.styleOld = dwExStyle;
3041 ss.styleNew = value;
3042 dprintf(("SetWindowLong GWL_EXSTYLE %x old %x new style %x", getWindowHandle(), dwExStyle, value));
3043 SendInternalMessageA(WM_STYLECHANGING,GWL_EXSTYLE,(LPARAM)&ss);
3044 setExStyle(ss.styleNew);
3045 updateWindowStyle(ss.styleOld,getStyle());
3046 SendInternalMessageA(WM_STYLECHANGED,GWL_EXSTYLE,(LPARAM)&ss);
3047 return ss.styleOld;
3048 }
3049 case GWL_STYLE:
3050 {
3051 STYLESTRUCT ss;
3052
3053 if(dwStyle == value)
3054 return value;
3055
3056 value &= ~(WS_VISIBLE | WS_CHILD); /* Some bits can't be changed this way (WINE) */
3057 ss.styleOld = getStyle();
3058 ss.styleNew = value | (ss.styleOld & (WS_VISIBLE | WS_CHILD));
3059 dprintf(("SetWindowLong GWL_STYLE %x old %x new style %x", getWindowHandle(), ss.styleOld, ss.styleNew));
3060 SendInternalMessageA(WM_STYLECHANGING,GWL_STYLE,(LPARAM)&ss);
3061 setStyle(ss.styleNew);
3062 updateWindowStyle(dwExStyle,ss.styleOld);
3063 SendInternalMessageA(WM_STYLECHANGED,GWL_STYLE,(LPARAM)&ss);
3064#ifdef DEBUG
3065 PrintWindowStyle(ss.styleNew, 0);
3066#endif
3067 return ss.styleOld;
3068 }
3069 case GWL_WNDPROC:
3070 oldval = (LONG)WINPROC_GetProc(win32wndproc, (fUnicode) ? WIN_PROC_32W : WIN_PROC_32A);
3071 //WINPROC_SetProc((HWINDOWPROC *)&win32wndproc, (WNDPROC)value, (fUnicode) ? WIN_PROC_32W : WIN_PROC_32A, WIN_PROC_WINDOW);
3072 WINPROC_SetProc((HWINDOWPROC *)&win32wndproc, (WNDPROC)value, WINPROC_GetProcType(win32wndproc), WIN_PROC_WINDOW);
3073 return oldval;
3074 case GWL_HINSTANCE:
3075 oldval = hInstance;
3076 hInstance = value;
3077 return oldval;
3078 case GWL_HWNDPARENT:
3079 return SetParent((HWND)value);
3080 case GWL_ID:
3081 oldval = getWindowId();
3082 setWindowId(value);
3083 return oldval;
3084 case GWL_USERDATA:
3085 oldval = userData;
3086 userData = value;
3087 return oldval;
3088 default:
3089 if(index >= 0 && index/4 < nrUserWindowLong)
3090 {
3091 oldval = userWindowLong[index/4];
3092 userWindowLong[index/4] = value;
3093 return oldval;
3094 }
3095 SetLastError(ERROR_INVALID_PARAMETER);
3096 return 0;
3097 }
3098}
3099//******************************************************************************
3100//******************************************************************************
3101ULONG Win32BaseWindow::GetWindowLongA(int index, BOOL fUnicode)
3102{
3103 ULONG value;
3104
3105 switch(index) {
3106 case GWL_EXSTYLE:
3107 value = dwExStyle;
3108 break;
3109 case GWL_STYLE:
3110 value = dwStyle;
3111 break;
3112 case GWL_WNDPROC:
3113 value = (LONG)WINPROC_GetProc(win32wndproc, (fUnicode) ? WIN_PROC_32W : WIN_PROC_32A);
3114 break;
3115 case GWL_HINSTANCE:
3116 value = hInstance;
3117 break;
3118 case GWL_HWNDPARENT:
3119 if(getParent()) {
3120 value = getParent()->getWindowHandle();
3121 }
3122 else value = 0;
3123 break;
3124 case GWL_ID:
3125 value = getWindowId();
3126 break;
3127 case GWL_USERDATA:
3128 value = userData;
3129 break;
3130 default:
3131 if(index >= 0 && index/4 < nrUserWindowLong)
3132 {
3133 value = userWindowLong[index/4];
3134 break;
3135 }
3136 SetLastError(ERROR_INVALID_PARAMETER);
3137 return 0;
3138 }
3139 dprintf2(("GetWindowLongA %x %d %x", getWindowHandle(), index, value));
3140 return value;
3141}
3142//******************************************************************************
3143//******************************************************************************
3144WORD Win32BaseWindow::SetWindowWord(int index, WORD value)
3145{
3146 WORD oldval;
3147
3148 if(index >= 0 && index/4 < nrUserWindowLong)
3149 {
3150 oldval = ((WORD *)userWindowLong)[index/2];
3151 ((WORD *)userWindowLong)[index/2] = value;
3152 return oldval;
3153 }
3154 SetLastError(ERROR_INVALID_PARAMETER);
3155 return 0;
3156}
3157//******************************************************************************
3158//******************************************************************************
3159WORD Win32BaseWindow::GetWindowWord(int index)
3160{
3161 if(index >= 0 && index/4 < nrUserWindowLong)
3162 {
3163 return ((WORD *)userWindowLong)[index/2];
3164 }
3165 SetLastError(ERROR_INVALID_PARAMETER);
3166 return 0;
3167}
3168//******************************************************************************
3169//******************************************************************************
3170void Win32BaseWindow::setWindowId(DWORD id)
3171{
3172 windowId = id;
3173 dprintf(("Set window ID to %x", id));
3174 OSLibSetWindowID(OS2HwndFrame, id);
3175}
3176//******************************************************************************
3177//******************************************************************************
3178Win32BaseWindow *Win32BaseWindow::GetWindowFromHandle(HWND hwnd)
3179{
3180 Win32BaseWindow *window;
3181
3182 if(HwGetWindowHandleData(hwnd, (DWORD *)&window) == TRUE) {
3183 return window;
3184 }
3185// dprintf2(("Win32BaseWindow::GetWindowFromHandle: not a win32 window %x", hwnd));
3186 return NULL;
3187}
3188//******************************************************************************
3189//******************************************************************************
3190Win32BaseWindow *Win32BaseWindow::GetWindowFromOS2Handle(HWND hwnd)
3191{
3192 Win32BaseWindow *win32wnd;
3193 DWORD magic;
3194
3195 if(hwnd == OSLIB_HWND_DESKTOP)
3196 {
3197 return windowDesktop;
3198 }
3199
3200 win32wnd = (Win32BaseWindow *)OSLibWinGetWindowULong(hwnd, OFFSET_WIN32WNDPTR);
3201 magic = OSLibWinGetWindowULong(hwnd, OFFSET_WIN32PM_MAGIC);
3202
3203 if(win32wnd && CheckMagicDword(magic)) {
3204 return win32wnd;
3205 }
3206// dprintf2(("Win32BaseWindow::GetWindowFromOS2Handle: not an Odin os2 window %x", hwnd));
3207 return 0;
3208}
3209//******************************************************************************
3210//******************************************************************************
3211Win32BaseWindow *Win32BaseWindow::GetWindowFromOS2FrameHandle(HWND hwnd)
3212{
3213 return GetWindowFromOS2Handle(OSLibWinWindowFromID(hwnd,OSLIB_FID_CLIENT));
3214}
3215//******************************************************************************
3216//******************************************************************************
3217HWND Win32BaseWindow::Win32ToOS2Handle(HWND hwnd)
3218{
3219 Win32BaseWindow *window = GetWindowFromHandle(hwnd);
3220
3221 if(window) {
3222 return window->getOS2WindowHandle();
3223 }
3224// dprintf2(("Win32BaseWindow::Win32ToOS2Handle: not a win32 window %x", hwnd));
3225 return hwnd;
3226}
3227//******************************************************************************
3228//******************************************************************************
3229HWND Win32BaseWindow::Win32ToOS2FrameHandle(HWND hwnd)
3230{
3231 Win32BaseWindow *window = GetWindowFromHandle(hwnd);
3232
3233 if(window) {
3234 return window->getOS2FrameWindowHandle();
3235 }
3236// dprintf2(("Win32BaseWindow::Win32ToOS2FrameHandle: not a win32 window %x", hwnd));
3237 return hwnd;
3238}
3239//******************************************************************************
3240//******************************************************************************
3241HWND Win32BaseWindow::OS2ToWin32Handle(HWND hwnd)
3242{
3243 Win32BaseWindow *window = GetWindowFromOS2Handle(hwnd);
3244
3245 if(window) {
3246 return window->getWindowHandle();
3247 }
3248 window = GetWindowFromOS2FrameHandle(hwnd);
3249 if(window) {
3250 return window->getWindowHandle();
3251 }
3252// dprintf2(("Win32BaseWindow::OS2ToWin32Handle: not a win32 window %x", hwnd));
3253 return 0;
3254// else return hwnd; //OS/2 window handle
3255}
3256//******************************************************************************
3257// GetNextDlgTabItem32 (USER32.276)
3258//******************************************************************************
3259HWND Win32BaseWindow::getNextDlgTabItem(HWND hwndCtrl, BOOL fPrevious)
3260{
3261 Win32BaseWindow *child, *nextchild, *lastchild;
3262 HWND retvalue;
3263
3264 if (hwndCtrl)
3265 {
3266 child = GetWindowFromHandle(hwndCtrl);
3267 if (!child)
3268 {
3269 retvalue = 0;
3270 goto END;
3271 }
3272 /* Make sure hwndCtrl is a top-level child */
3273 while ((child->getStyle() & WS_CHILD) && (child->getParent() != this))
3274 {
3275 child = child->getParent();
3276 if(child == NULL) break;
3277 }
3278
3279 if (!child || (child->getParent() != this))
3280 {
3281 retvalue = 0;
3282 goto END;
3283 }
3284 }
3285 else
3286 {
3287 /* No ctrl specified -> start from the beginning */
3288 child = (Win32BaseWindow *)getFirstChild();
3289 if (!child)
3290 {
3291 retvalue = 0;
3292 goto END;
3293 }
3294
3295 if (!fPrevious)
3296 {
3297 while (child->getNextChild())
3298 {
3299 child = (Win32BaseWindow *)child->getNextChild();
3300 }
3301 }
3302 }
3303
3304 lastchild = child;
3305 nextchild = (Win32BaseWindow *)child->getNextChild();
3306 while (TRUE)
3307 {
3308 if (!nextchild) nextchild = (Win32BaseWindow *)getFirstChild();
3309
3310 if (child == nextchild) break;
3311
3312 if ((nextchild->getStyle() & WS_TABSTOP) && (nextchild->getStyle() & WS_VISIBLE) &&
3313 !(nextchild->getStyle() & WS_DISABLED))
3314 {
3315 lastchild = nextchild;
3316 if (!fPrevious) break;
3317 }
3318 nextchild = (Win32BaseWindow *)nextchild->getNextChild();
3319 }
3320 retvalue = lastchild->getWindowHandle();
3321
3322END:
3323 return retvalue;
3324}
3325//******************************************************************************
3326//******************************************************************************
3327HWND Win32BaseWindow::getNextDlgGroupItem(HWND hwndCtrl, BOOL fPrevious)
3328{
3329 Win32BaseWindow *child, *nextchild, *lastchild;
3330 HWND retvalue;
3331
3332 if (hwndCtrl)
3333 {
3334 child = GetWindowFromHandle(hwndCtrl);
3335 if (!child)
3336 {
3337 retvalue = 0;
3338 goto END;
3339 }
3340 /* Make sure hwndCtrl is a top-level child */
3341 while ((child->getStyle() & WS_CHILD) && (child->getParent() != this))
3342 {
3343 child = child->getParent();
3344 if(child == NULL) break;
3345 }
3346
3347 if (!child || (child->getParent() != this))
3348 {
3349 retvalue = 0;
3350 goto END;
3351 }
3352 }
3353 else
3354 {
3355 /* No ctrl specified -> start from the beginning */
3356 child = (Win32BaseWindow *)getFirstChild();
3357 if (!child)
3358 {
3359 retvalue = 0;
3360 goto END;
3361 }
3362
3363 if (fPrevious)
3364 {
3365 while (child->getNextChild())
3366 {
3367 child = (Win32BaseWindow *)child->getNextChild();
3368 }
3369 }
3370 }
3371
3372 lastchild = child;
3373 nextchild = (Win32BaseWindow *)child->getNextChild();
3374 while (TRUE)
3375 {
3376 if (!nextchild || (nextchild->getStyle() & WS_GROUP))
3377 {
3378 /* Wrap-around to the beginning of the group */
3379 Win32BaseWindow *pWndTemp;
3380
3381 nextchild = (Win32BaseWindow *)getFirstChild();
3382
3383 for(pWndTemp = nextchild;pWndTemp;pWndTemp = (Win32BaseWindow *)pWndTemp->getNextChild())
3384 {
3385 if (pWndTemp->getStyle() & WS_GROUP)
3386 nextchild = pWndTemp;
3387
3388 if (pWndTemp == child)
3389 break;
3390 }
3391
3392 }
3393 if (nextchild == child)
3394 break;
3395
3396 if ((nextchild->getStyle() & WS_VISIBLE) && !(nextchild->getStyle() & WS_DISABLED))
3397 {
3398 lastchild = nextchild;
3399
3400 if (!fPrevious)
3401 break;
3402 }
3403
3404 nextchild = (Win32BaseWindow *)nextchild->getNextChild();
3405 }
3406 retvalue = lastchild->getWindowHandle();
3407END:
3408 return retvalue;
3409}
3410//******************************************************************************
3411//******************************************************************************
3412#ifdef DEBUG
3413void PrintWindowStyle(DWORD dwStyle, DWORD dwExStyle)
3414{
3415 char style[256] = "";
3416 char exstyle[256] = "";
3417
3418 /* Window styles */
3419 if(dwStyle & WS_CHILD)
3420 strcat(style, "WS_CHILD ");
3421 if(dwStyle & WS_POPUP)
3422 strcat(style, "WS_POPUP ");
3423 if(dwStyle & WS_VISIBLE)
3424 strcat(style, "WS_VISIBLE ");
3425 if(dwStyle & WS_DISABLED)
3426 strcat(style, "WS_DISABLED ");
3427 if(dwStyle & WS_CLIPSIBLINGS)
3428 strcat(style, "WS_CLIPSIBLINGS ");
3429 if(dwStyle & WS_CLIPCHILDREN)
3430 strcat(style, "WS_CLIPCHILDREN ");
3431 if(dwStyle & WS_MAXIMIZE)
3432 strcat(style, "WS_MAXIMIZE ");
3433 if(dwStyle & WS_MINIMIZE)
3434 strcat(style, "WS_MINIMIZE ");
3435 if(dwStyle & WS_GROUP)
3436 strcat(style, "WS_GROUP ");
3437 if(dwStyle & WS_TABSTOP)
3438 strcat(style, "WS_TABSTOP ");
3439
3440 if((dwStyle & WS_CAPTION) == WS_CAPTION)
3441 strcat(style, "WS_CAPTION ");
3442 if(dwStyle & WS_DLGFRAME)
3443 strcat(style, "WS_DLGFRAME ");
3444 if(dwStyle & WS_BORDER)
3445 strcat(style, "WS_BORDER ");
3446
3447 if(dwStyle & WS_VSCROLL)
3448 strcat(style, "WS_VSCROLL ");
3449 if(dwStyle & WS_HSCROLL)
3450 strcat(style, "WS_HSCROLL ");
3451 if(dwStyle & WS_SYSMENU)
3452 strcat(style, "WS_SYSMENU ");
3453 if(dwStyle & WS_THICKFRAME)
3454 strcat(style, "WS_THICKFRAME ");
3455 if(dwStyle & WS_MINIMIZEBOX)
3456 strcat(style, "WS_MINIMIZEBOX ");
3457 if(dwStyle & WS_MAXIMIZEBOX)
3458 strcat(style, "WS_MAXIMIZEBOX ");
3459
3460 if(dwExStyle & WS_EX_DLGMODALFRAME)
3461 strcat(exstyle, "WS_EX_DLGMODALFRAME ");
3462 if(dwExStyle & WS_EX_ACCEPTFILES)
3463 strcat(exstyle, "WS_EX_ACCEPTFILES ");
3464 if(dwExStyle & WS_EX_NOPARENTNOTIFY)
3465 strcat(exstyle, "WS_EX_NOPARENTNOTIFY ");
3466 if(dwExStyle & WS_EX_TOPMOST)
3467 strcat(exstyle, "WS_EX_TOPMOST ");
3468 if(dwExStyle & WS_EX_TRANSPARENT)
3469 strcat(exstyle, "WS_EX_TRANSPARENT ");
3470
3471 if(dwExStyle & WS_EX_MDICHILD)
3472 strcat(exstyle, "WS_EX_MDICHILD ");
3473 if(dwExStyle & WS_EX_TOOLWINDOW)
3474 strcat(exstyle, "WS_EX_TOOLWINDOW ");
3475 if(dwExStyle & WS_EX_WINDOWEDGE)
3476 strcat(exstyle, "WS_EX_WINDOWEDGE ");
3477 if(dwExStyle & WS_EX_CLIENTEDGE)
3478 strcat(exstyle, "WS_EX_CLIENTEDGE ");
3479 if(dwExStyle & WS_EX_CONTEXTHELP)
3480 strcat(exstyle, "WS_EX_CONTEXTHELP ");
3481 if(dwExStyle & WS_EX_RIGHT)
3482 strcat(exstyle, "WS_EX_RIGHT ");
3483 if(dwExStyle & WS_EX_LEFT)
3484 strcat(exstyle, "WS_EX_LEFT ");
3485 if(dwExStyle & WS_EX_RTLREADING)
3486 strcat(exstyle, "WS_EX_RTLREADING ");
3487 if(dwExStyle & WS_EX_LTRREADING)
3488 strcat(exstyle, "WS_EX_LTRREADING ");
3489 if(dwExStyle & WS_EX_LEFTSCROLLBAR)
3490 strcat(exstyle, "WS_EX_LEFTSCROLLBAR ");
3491 if(dwExStyle & WS_EX_RIGHTSCROLLBAR)
3492 strcat(exstyle, "WS_EX_RIGHTSCROLLBAR ");
3493 if(dwExStyle & WS_EX_CONTROLPARENT)
3494 strcat(exstyle, "WS_EX_CONTROLPARENT ");
3495 if(dwExStyle & WS_EX_STATICEDGE)
3496 strcat(exstyle, "WS_EX_STATICEDGE ");
3497 if(dwExStyle & WS_EX_APPWINDOW)
3498 strcat(exstyle, "WS_EX_APPWINDOW ");
3499
3500 dprintf(("Window style: %x %s", dwStyle, style));
3501 dprintf(("Window exStyle: %x %s (FS = %x)", dwExStyle, exstyle, GetFS()));
3502}
3503#endif
3504//******************************************************************************
3505//******************************************************************************
3506
3507GenericObject *Win32BaseWindow::windows = NULL;
Note: See TracBrowser for help on using the repository browser.