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

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

tasklist changes

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