source: trunk/src/user32/win32wfake.cpp@ 22145

Last change on this file since 22145 was 22135, checked in by dmik, 8 years ago

user32: Make r22134 actually work.

It would not due to using a virtual function from the base destructor
(which always calls the base version instead of the derived).

File size: 9.3 KB
Line 
1/* $Id: win32wfake.cpp,v 1.5 2003-04-24 17:20:42 sandervl Exp $ */
2/*
3 * Win32 Fake Window Class for OS/2
4 *
5 *
6 * Copyright 2002 Sander van Leeuwen (sandervl@innotek.de)
7 *
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
12#include <os2win.h>
13#include <stdlib.h>
14#include <string.h>
15#include <dbglog.h>
16#include <win/winproc.h>
17#include "win32wbase.h"
18#include "win32wfake.h"
19#include "oslibwin.h"
20#include "win32wndhandle.h"
21#include "pmwindow.h"
22
23#define DBG_LOCALLOG DBG_win32wfake
24#include "dbglocal.h"
25
26/** The Odin HWND Property - must be unique for this (custom)build. */
27char Win32FakeWindow::szPropOdinHandle[64] = "OdinFakeHWND";
28/** Flag which tells if we've inited or not. */
29BOOL Win32FakeWindow::fInited = FALSE;
30
31/**
32 * Creates a fake Odin window for an existing OS/2 window.
33 *
34 * @returns odin handle to the fake window.
35 * @returns NULL on failure.
36 * @param hwndOS2 Window handle.
37 * @param classAtom The atom of the Odin window class.
38 * @author Sander van Leeuwen <sandervl@innotek.de>
39 * @author knut st. osmundsen <bird@anduin.net>
40 */
41HWND WIN32API CreateFakeWindowEx(HWND hwndOS2, ATOM classAtom)
42{
43 Win32FakeWindow *window;
44
45 /*
46 * Check if already faked - fail.
47 */
48 window = Win32FakeWindow::GetWindowFromOS2Handle(hwndOS2);
49 if (window)
50 {
51 dprintf(("CreateFakeWindowEx: already faked!!! (hwndOS2=%x hwndOdin=%x)",
52 hwndOS2, window->getWindowHandle()));
53 return window->getWindowHandle();
54 }
55
56 /*
57 * Now proceed.
58 */
59 window = new Win32FakeWindow(hwndOS2, classAtom);
60 if (window == NULL)
61 {
62 dprintf(("Win32FakeWindow creation failed for %x!!!", hwndOS2));
63 return 0;
64 }
65 HWND hwnd = window->getWindowHandle();
66
67 // set myself as last active popup / window
68 window->setLastActive( hwnd );
69
70 RELEASE_WNDOBJ(window);
71 dprintf(("CreateFakeWindowEx: created %x for %x", hwnd, hwndOS2));
72 return hwnd;
73}
74//******************************************************************************
75//******************************************************************************
76BOOL WIN32API DestroyFakeWindow(HWND hwnd)
77{
78 Win32BaseWindow *window;
79
80 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
81 if (!window) {
82 dprintf(("DestroyFakeWindow, window %x not found", hwnd));
83 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
84 return 0;
85 }
86 delete window;
87 return TRUE;
88}
89//******************************************************************************
90//******************************************************************************
91Win32FakeWindow::Win32FakeWindow(HWND hwndOS2, ATOM classAtom)
92 : Win32BaseWindow()
93{
94 if (!fInited) init();
95
96 fFakeWindow = TRUE;
97
98 OS2Hwnd = OS2HwndFrame = hwndOS2;
99
100 /* Find the window class */
101 windowClass = Win32WndClass::FindClass(NULL, (LPSTR)classAtom);
102 if (!windowClass)
103 {
104 char buffer[32];
105 GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) );
106 dprintf(("Bad class '%s'", buffer ));
107 DebugInt3();
108 }
109
110 //Allocate window words
111 nrUserWindowBytes = windowClass->getExtraWndBytes();
112 if(nrUserWindowBytes) {
113 userWindowBytes = (char *)_smalloc(nrUserWindowBytes);
114 memset(userWindowBytes, 0, nrUserWindowBytes);
115 }
116
117 WINPROC_SetProc((HWINDOWPROC *)&win32wndproc, windowClass->getWindowProc((isUnicode) ? WNDPROC_UNICODE : WNDPROC_ASCII), WINPROC_GetProcType((HWINDOWPROC)windowClass->getWindowProc((isUnicode) ? WNDPROC_UNICODE : WNDPROC_ASCII)), WIN_PROC_WINDOW);
118 hInstance = NULL;
119 dwStyle = WS_VISIBLE;
120 dwOldStyle = dwStyle;
121 dwExStyle = 0;
122
123 //We pretend this window has no parent and its position is in screen coordinates
124 OSLibWinQueryWindowClientRect(OS2Hwnd, &rectClient);
125 OSLibQueryWindowRectAbsolute (OS2Hwnd, &rectWindow);
126
127 //Store the window handle as a property of the OS/2 window.
128 if (!OSLibSetProperty(OS2Hwnd, szPropOdinHandle, (void*)getWindowHandle(), 0))
129 {
130 dprintf(("%s: f**k! WinSetProperty(%x,%s,%x,0) failed!!!", __FUNCTION__,
131 hwndOS2, szPropOdinHandle, getWindowHandle()));
132 }
133
134 //See if parent window is either odin or fake window.
135 Win32BaseWindow * pParent = NULL;
136 HWND hwndParentOS2 = OSLibWinQueryWindow(OS2Hwnd, QWOS_PARENT);
137 if (hwndParentOS2 != OSLIB_HWND_DESKTOP)
138 {
139 pParent = Win32FakeWindow::GetWindowFromOS2Handle(hwndParentOS2);
140 if (!pParent)
141 pParent = Win32BaseWindow::GetWindowFromOS2Handle(hwndParentOS2);
142 if (pParent)
143 {
144 setParent(pParent);
145 dprintf(("%s: hwndParentOS2=%x %s window, set as parent.", __FUNCTION__,
146 hwndParentOS2, pParent->isFakeWindow() ? "fake" : "odin"));
147 dwStyle |= WS_CHILD;
148 }
149 else
150 {
151 dprintf(("%s: hwndParentOS2=%x but not a fake nor odin window.", __FUNCTION__, hwndParentOS2));
152 }
153 }
154
155 //See if owner widnow is either odin or fake window.
156 HWND hwndOwnerOS2 = OSLibWinQueryWindow(OS2Hwnd, QWOS_OWNER);
157 if (hwndOwnerOS2 != OSLIB_HWND_DESKTOP)
158 {
159 Win32BaseWindow * pOwner;
160 if (hwndOwnerOS2 == hwndParentOS2)
161 pOwner = pParent;
162 else
163 {
164 pOwner = Win32FakeWindow::GetWindowFromOS2Handle(hwndOwnerOS2);
165 if (!pOwner)
166 pOwner = Win32BaseWindow::GetWindowFromOS2Handle(hwndOwnerOS2);
167 }
168 if (pOwner)
169 {
170 setOwner(pOwner);
171 dprintf(("%s: hwndOwnerOS2=%x %s window, set as owner.", __FUNCTION__,
172 hwndOwnerOS2, pOwner->isFakeWindow() ? "fake" : "odin"));
173 dwStyle |= WS_CHILD;
174 }
175 else
176 {
177 dprintf(("%s: hwndOwnerOS2=%x but not a fake nor odin window.", __FUNCTION__, hwndOwnerOS2));
178 }
179 }
180
181
182 setOldPMWindowProc(PMWinSubclassFakeWindow(OS2Hwnd));
183}
184//******************************************************************************
185//******************************************************************************
186Win32FakeWindow::~Win32FakeWindow()
187{
188 OSLibRemoveProperty(OS2Hwnd, szPropOdinHandle);
189}
190//******************************************************************************
191//******************************************************************************
192PRECT Win32FakeWindow::getWindowRect()
193{
194 //the coordinates can change without us being notified, so recheck every time
195
196 Win32BaseWindow * pParent = getParent();
197 if (pParent)
198 {
199 SWP swp;
200 if (OSLibWinQueryWindowPos(OS2Hwnd, &swp))
201 {
202 ULONG y = pParent->getWindowHeight();
203 rectWindow.left = swp.x;
204 rectWindow.right = swp.x + swp.cx;
205 rectWindow.top = y - swp.y - swp.cy;
206 rectWindow.bottom = y - swp.y;
207 }
208 }
209 else
210 OSLibQueryWindowRectAbsolute(OS2Hwnd, &rectWindow);
211
212 return &rectWindow;
213}
214//******************************************************************************
215//******************************************************************************
216BOOL Win32FakeWindow::SetWindowPos(HWND hwndInsertAfter, int x, int y, int cx,
217 int cy, UINT fuFlags, BOOL fShowWindow)
218{
219 // we don't trust input either.
220 dprintf(("Win32FakeWindow::SetWindowPos; don't change window position, just update internal position"));
221
222 OSLibWinQueryWindowClientRect(OS2Hwnd, &rectClient);
223 getWindowRect();
224 return TRUE;
225}
226//******************************************************************************
227//******************************************************************************
228
229/**
230 * Locates window in linked list and increases reference count if found.
231 * The window object msut be unreferenced after usage.
232 *
233 * @returns Pointer to fake window.
234 * @returns NULL if not found.
235 * @param hwndOS2 OS/2 window handle of the fake window.
236 */
237Win32FakeWindow *Win32FakeWindow::GetWindowFromOS2Handle(HWND hwndOS2)
238{
239 if (!fInited) init();
240
241 HWND hwnd = (HWND)OSLibQueryProperty(hwndOS2, szPropOdinHandle);
242 Win32BaseWindow *pWindow = GetWindowFromHandle(hwnd);
243 if (pWindow)
244 {
245 if (pWindow->isFakeWindow())
246 return (Win32FakeWindow*)pWindow;
247 DebugInt3();
248 }
249 dprintf2(("Win32FakeWindow::GetWindowFromOS2Handle(%x) -> null", hwndOS2));
250 return NULL;
251}
252
253
254/**
255 * Init the global(s).
256 * It will make the name property unique among the odin instances.
257 *
258 * This will chagne szPropOdinHandle and fInited.
259 */
260void Win32FakeWindow::init()
261{
262 if (fInited)
263 return;
264
265 /*
266 * Get the name of this dll.
267 */
268 extern int _System DosQueryModFromEIP(HMODULE *phMod, ULONG *pObjNum, ULONG BuffLen, PCHAR pBuff, ULONG *pOffset, ULONG Address);
269 char szModName[260];
270 HMODULE hmod;
271 ULONG iObj, offObj;
272 USHORT sel = GetFS();
273
274 int rc = DosQueryModFromEIP(&hmod, &iObj, sizeof(szModName), &szModName[0], &offObj, (ULONG)Win32FakeWindow::init);
275 SetFS(sel);
276
277 if (rc)
278 {
279 dprintf(("Win32FakeWindow::init: DosQueryModFromEIP failed!!!"));
280 DebugInt3();
281 return;
282 }
283 char *psz = strrchr(szModName, '\\');
284 if (!psz)
285 psz = szModName;
286 if (strchr(szModName, '.'))
287 *strchr(szModName, '.') = '\0';
288
289 fInited = 1;
290 strcat(szPropOdinHandle, psz);
291 dprintf(("Win32FakeWindow::init: szPropOdinHandle='%s'", szPropOdinHandle));
292}
293
Note: See TracBrowser for help on using the repository browser.