createSystemChild and createWindow hang on Windows trying to create a child window

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

createSystemChild and createWindow hang on Windows trying to create a child window

Don Walker-3
I'm posting this to the dev mailing list as I'm not sure which project
specific lists I should be posting to. Let me know where to redirect this if
necessary.

I'm trying to display Open Office in a child window on Windows. I've tried
both the Hack and Legal approaches described in the 2.0 Developer's Guide,
section 6.1.7 Java Window Integration, Using the Window Handle (pages
417-418 in my copy). In both cases my code hangs:

a) in the createSystemChild call using the Legal approach.

b) in the createWindow call using the Hack approach.

My code is written in C++ using Visual Studio 2005 on Windows XP Pro, SP2,
fully updated. I'm running Open Office 2.0.1rc5 with the SDK version
2.0.0rc2. I have working code that can bootstrap the local Open Office,
open, save and close a document, add listeners and keyhandlers, and shutdown
gracefully. The child window problem is the only one I haven't been able to
solve.

I'm aware of the ActiveX control, so_activex.dll, that is included in the OO
install. It doesn't provide the functionality that I need. I'm also aware
that the source code for this control is included with the SDK in <SDK
Root>\examples\OLE\activex. I've even built the control from the source code
and tested it to confirm that it still works when built with VS 2005.

I've used Spy++ to analyze the windows created by the working OO ActiveX
control, and those created by my ActiveX control up to the moment that the
call hangs. Spy++ shows that my control creates the same child window of
window class SALTMPSUBFRAME that the OO control creates. Everything in the
Spy++ Window Properties looks the same except for the fact that the Window
Proc on the General tab shows as unavailable. I assume that this is an
indication that the window is still in limbo because the call hung. The OO
QuickStarter icon is unresponsive while the call is hung.

There are differences between the code listed below and the example in the
Dev guide:

a) I use cppu:bootstrap() to get my initial context. This connects to OO
through a named pipe. All the Dev guide examples connect using sockets.

b) I use XMultiComponentFactory::createInstanceWithContext instead of
XMultiServiceFactory::createInstance. This follows the recommendations in
the Dev Guide section 3.3.2 Service Manager and Component Context.

Bootstrap code:

        Reference<XComponentContext> xLocalContext;
        Reference<XMultiComponentFactory> xServiceManager;

        if (!xLocalContext.is())
                xLocalContext = bootstrap();
        if (!xServiceManager.is())
                xServiceManager = xLocalContext->getServiceManager();

Child window code: HWND hwnd is passed in from the control.

        Reference<XToolkit>
xToolkit(xServiceManager->createInstanceWithContext(
                OUString::createFromAscii("com.sun.star.awt.Toolkit"),
xLocalContext),
                UNO_QUERY);
Either this:
        // Legal solution from section 6.1.7 of the Dev Guide (pg. 417-418)
        Reference<XSystemChildFactory> xFac(xToolkit, UNO_QUERY);
        Any anyHwnd;
        sal_Int32 int32Hwnd = (long)hwnd;
        anyHwnd <<= int32Hwnd;
        sal_uInt8 processID[16];
        rtl_getGlobalProcessId(processID);
        Reference<XWindowPeer> xPeer = xFac->createSystemChild(anyHwnd,
                Sequence<sal_Int8>((sal_Int8*)processID, 16),
                com::sun::star::lang::SystemDependent::SYSTEM_WIN32);
        // End Legal Solution
or this:
        // Hack
        // Note that VTOOWindowPeer is an implementation of XWindowPeer and
XSystemDependentWindowPeer
        // that returns the window handle to createWindow.
        Reference<XWindowPeer> xParentPeer = new VTOOWindowPeer(hwnd);
        WindowDescriptor aDescriptor;
        aDescriptor.Type = WindowClass::WindowClass_TOP;
        aDescriptor.WindowServiceName =
OUString::createFromAscii("workwindow");
        aDescriptor.ParentIndex = 1;
        aDescriptor.Parent = xParentPeer;
        aDescriptor.Bounds = com::sun::star::awt::Rectangle(0,0,0,0);
        aDescriptor.WindowAttributes = WindowAttribute::SHOW +
WindowAttribute::SIZEABLE;
        Reference<XWindowPeer> xPeer = xToolkit->createWindow(aDescriptor);
        // End Hack
hangs.

Any help would be appreciated.

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: createSystemChild and createWindow hang on Windows trying to create a child window

Andreas Schlüns
Hello Don,

<snip>

> I've used Spy++ to analyze the windows created by the working OO ActiveX
> control, and those created by my ActiveX control up to the moment that the
> call hangs. Spy++ shows that my control creates the same child window of
> window class SALTMPSUBFRAME that the OO control creates. Everything in the
> Spy++ Window Properties looks the same except for the fact that the Window
> Proc on the General tab shows as unavailable. I assume that this is an
> indication that the window is still in limbo because the call hung. The OO
> QuickStarter icon is unresponsive while the call is hung.

If I remember right there was similar problems on developing the ActiveX
control of OOo. And it was reasoned by some synchronous callbacks
related to the hWnd.

Please analyze the code of the ActiveX control, if you can find
something related to threads. I will ask the right developers here too
.. so I can provide some more details later. stay tuned

On the other side I know: providing the hWnd to OOo isnt enough ... not
on windows. The bean uses sub classing of the WindowProc to full fill
it's job. Otherwhise the office window isnt shown as child of your
window correctly. Especialy resizes are not handled by OOo for external
windows ... so you have to make sure that the OOo window is shown
full-size within your hWnd area.
The related code can be found on:

http://api.openoffice.org/source/browse/api/bean/native/win32/com_sun_star_comp_beans_LocalOfficeWindow.c?rev=1.3&content-type=text/vnd.viewcvs-markup
http://api.openoffice.org/source/browse/api/bean/native/unix/...

The most interesting parts are:

JNIEXPORT jlong JNICALL
Java_com_sun_star_comp_beans_LocalOfficeWindow_getNativeWindow
(JNIEnv * env, jobject obj_this)
{
     ...

     /* Register own window procedure
        Do it one times only! Otherwhise
        multiple instances will be registered
        and calls on such construct produce
        a stack overflow.
      */
     if (GetProp( hWnd, OLD_PROC_KEY )==0)
     {
         hFuncPtr =
        SetWindowLong( hWnd, GWL_WNDPROC,
                       (DWORD)OpenOfficeWndProc );
         SetProp( hWnd, OLD_PROC_KEY, (HANDLE)hFuncPtr );
     }
     ...
}

static LRESULT APIENTRY OpenOfficeWndProc(
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
     ....
     return CallWindowProc(GetProp(hWnd, OLD_PROC_KEY),
   hWnd, uMsg, wParam, lParam);
}

You should handle the same events WM_PARENTNOTIFY and WM_SIZE for your
window.

Regards
Andreas

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: createSystemChild and createWindow hang on Windows trying to create a child window

Andreas Schlüns
In reply to this post by Don Walker-3
Hello Don,

> I'm trying to display Open Office in a child window on Windows. I've tried
> both the Hack and Legal approaches described in the 2.0 Developer's Guide,
> section 6.1.7 Java Window Integration, Using the Window Handle (pages
> 417-418 in my copy). In both cases my code hangs:

It seams that exactly the synchronous execution of the createWindow() /
createSystemChild() methods is the problem. Because you call OOo
synchronously. Doing this your own process is blocked. Now OOo uses your
provided hWnd and make some call's on it. This forces the windows API to
call your process back to handle e.g. incoming window messages. But they
cant be executed ... because your process is blocked.

May be it would help, if you use an own thread to create your XWindow
without blocking your process.

BTW. The OOo ActiveX control uses COM internaly. And COM makes something
special related to message loops internaly. The same for Java. Because
in java the UI will be executed in it's own thread.

Hopefully this will help to solve your problem.
Regards
Andreas

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

RE: createSystemChild and createWindow hang on Windows trying to create a child window

Don Walker-3
Hi Andreas,

Your reply make sense. I will try doing the create call in another thread.
This may take a few days as the  OO work is no longer my top priority. I
will let you know one way or the other.

In response to your previous email about the WindowProc I'm hoping that the
technique I copied from the OO ActiveX control of creating a child window
with a ::DefWindowProc and using that window's hwnd for the create call will
be sufficient. I'll find out once I get the create call working.

Thanks,
Don

-----Original Message-----
From: Andreas Schlüns [mailto:[hidden email]]
Sent: January 19, 2006 3:55
To: [hidden email]
Subject: Re: [dev] createSystemChild and createWindow hang on Windows trying
to create a child window


Hello Don,

> I'm trying to display Open Office in a child window on Windows. I've
> tried both the Hack and Legal approaches described in the 2.0
> Developer's Guide, section 6.1.7 Java Window Integration, Using the
> Window Handle (pages 417-418 in my copy). In both cases my code hangs:

It seams that exactly the synchronous execution of the createWindow() /
createSystemChild() methods is the problem. Because you call OOo
synchronously. Doing this your own process is blocked. Now OOo uses your
provided hWnd and make some call's on it. This forces the windows API to
call your process back to handle e.g. incoming window messages. But they
cant be executed ... because your process is blocked.

May be it would help, if you use an own thread to create your XWindow
without blocking your process.

BTW. The OOo ActiveX control uses COM internaly. And COM makes something
special related to message loops internaly. The same for Java. Because
in java the UI will be executed in it's own thread.

Hopefully this will help to solve your problem.
Regards
Andreas

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]