2

I'm writing a screensaver in Java. It's primarily for Windows, though I'd prefer it to be as portable as practical.

According to http://support.microsoft.com/kb/182383, when a screensaver is invoked with command line args /p HWND, the screensaver should "Preview Screen Saver as child of window ." Presumably this is how screensavers should their little preview in the Screen Saver Settings dialog.

So how, in Java, do you create a JFrame or JComponent that's a child of a window that belongs to somebody else? I've looked at Embed HWND (Window Handle) in a JPanel which is sort of the reverse question: The developer controls the parent window and wants to embed a child window. In my case, I control a child component that I want into embed into a parent that is not "mine". Can I use JNA to do that?

I'd rather not have to maintain C code in addition to Java code. (So JNI is not preferred.) I understand that JDIC was supposed to meet this kind of need, but I've read that JDIC is essentially dead.

I'm running Windows 7, FWIW.

Community
  • 1
  • 1
LarsH
  • 27,481
  • 8
  • 94
  • 152
  • 1
    not an expert in this domain, but would think this is not possible because your java app would have to take over a windows process - and that seems wrong from a security perspective. – dbrin Mar 27 '12 at 04:42
  • @DmitryB: I'd like to hear more about that. It's clearly possible for some programs to do (all compliant screensavers do)... yet not for a Java program? – LarsH Mar 27 '12 at 04:45
  • @DmitryB: see e.g. http://www.harding.edu/fmccown/screensaver/screensaver.html for a C# implementation that does this: `SetParent(this.Handle, PreviewWndHandle);` – LarsH Mar 27 '12 at 04:52
  • hmmm yeah ... Java is not "any of the .NET programming languages" as per tutorial :) I had to use JNA library to talk to a dll - it was tough. every method had to be exported just so and all of the variables had to line up. – dbrin Mar 27 '12 at 05:05
  • 1
    @DmitryB: the fact that Java is not "any of the .NET programming languages" is a valid point, but it simply means that that tutorial does not say you can do it in Java. It does **not** mean the tutorial says you *cannot* do it in Java. And (my point was) the fact that you can do it in .NET suggests that it is not "wrong from a security perspective" in Windows. But I would be happy to see further details showing that `SetParent()` is somehow "special", and is not possible in pure Java. – LarsH Mar 27 '12 at 10:52
  • @DmitryB: can you tell me more about what you did with JNA and the DLL? What DLL did you use? I thought JNA was supposed to make it a lot easier than JNI to work with native libraries. – LarsH Mar 27 '12 at 10:57
  • @DmitryB: I don't mind declaring a few native Windows functions in Java (as shown in http://en.wikipedia.org/wiki/Java_Native_Access) if that's all it takes. That would still count as "pure Java" (close enough) for the purpose of awarding this bounty. If you're willing to share (enough of) your code. – LarsH Mar 27 '12 at 11:06
  • Oh, i don't think my use is of any help here. We basically executed some code that was written in C or C++ that was packaged into a binary library (dll on win and lib? on linux). The code was all custom. Java loaded the dll like a jar using JNA and exposed functions were callable via normal Java calls. Your use case is very much reverse it seems. – dbrin Mar 28 '12 at 05:17

2 Answers2

0

Have a look at Jdic, it has an SDK for screensavers, so at least you may study their code..

Mikhail
  • 1,223
  • 14
  • 25
  • Correction (note to self): the sdk svn checkout URL is `https://svn.java.net/svn/jdic~svn/trunk`. The SaverBeans SDK works by using a "pre-built native library", so that won't be a pure java solution per se, but it might be something I can use via JNA. – LarsH Mar 27 '12 at 20:50
  • Well... this seems to be a dead end. The only thing I could find in the src tree resembling what I was asking for above is in trunk/src/incubator/screensaver/src/ant-native/win32/saverbeans-win32.cpp, which says "The current strategy for this is to create an EmbeddedFrame that is a child of this native window and snag the Graphics object from it." But I can't tell whether it actually applies, nor how to use it if it does. AFAICT, the java code does not seem to know about fitting into a child preview window. Nor can I find a download of the SaverBeans Screensaver pack to verify (Not found). – LarsH Mar 27 '12 at 21:31
0

You need to call a win32 api. That api is in C. You'll need to the interop layer to do this. I think every option will be gross.

For Java, I think that is JNI. See this on how to do it.

You will also need to pass that value to SetParent.

The screen saver runs at the same security rights as the screensaver dialog so this isn't a security issue.

Community
  • 1
  • 1
  • The article I referenced (http://stackoverflow.com/questions/4809713/embed-hwnd-window-handle-in-a-jpanel) indicates SetParent() and suggests it can be done with JNA, which as I mentioned, is preferred over JNI. Are you saying it can't be done with JNA? – LarsH Apr 03 '12 at 02:36