Hi,
I ran into a strange problem. Sys.alert(...) is no longer working. It was working on my computer some time ago. However during tests today, I realised that it does no longer show a message dialog. I only get the default windows error sound "plonk" but no dialog.
import org.lwjgl.Sys;
import org.lwjgl.opengl.Display;
public class SysAlertTest {
public static void main(String[] args) {
Sys.alert("Title", "Message!");
try {
Display.create();
Sys.alert("Title", "Message!");
} catch (Exception ex) {
System.out.println(ex);
}
}
}
I tried both before and after Display.create(...). The above code plays the error sound twice but shows no dialog.
I ran a debugging session and found out that the error sound plays when nAlert(...) in the Windows implementation of Sys gets called.
This is on:
Windows XP SP3
Java 6
LWJGL 2.0.1
Strangely the webstart LWJGL SysTest demo works and shows a dialog. If I download its source and run it without webstart, it no longer works.
Is there something wrong with my code? Am I missing something?
Can reproduce that it doesn't show prior to displaying a window. I tried creating a completely new native function and regardless of what I do it doesn't show (GetDesktopWindow, NULL, etc)... not sure why.
Any takers?
Quote from: Matzon on March 16, 2009, 20:35:18
Can reproduce that it doesn't show prior to displaying a window.
Ah thanks, that's a good hint. Looks like the necessary (AWT?) libraries do not get loaded by Sys.alert(). This would explain why it works with web start, which shows a splash screen before the actual application gets launched.
First, I tried to create a simple frame (
java.awt.Frame frame = new java.awt.Frame();) prior to
Sys.alert() and it worked. So I checked constructors and static parts of
Frame/Window. They load certain native libraries in their
static {} constructor via
Toolkit. Since all they use is private or package-only, I tried
Toolkit.getDefaultToolkit(); and it worked:
public static void main(String[] args) {
Toolkit.getDefaultToolkit();
Sys.alert("Title", "Message!"); // Works
}
During the construction of java.awt.Toolkit libraries get loaded. Issueing this load call prior to using Sys.alert() also fixes it:
public static void main(String[] args) {
java.security.AccessController.doPrivileged(new sun.security.action.LoadLibraryAction("awt"));
Sys.alert("Title", "Message!"); // Works too
}
I don't really know what the side effects of both calls are. Is it a problem to instantiate a default Toolkit in some cases? Do libraries get loaded twice with the second? Are libraries unloaded at some point?
At least it's a workaround :)
This is still reproducible in 2.2.1 on Windows XP.
Without the Toolkit.getDefaultToolkit(); workaround, there's no visible alert.
I have not been working on fixing this - so yes still there. Absolutely clueless as to why its happening.
Found a comment in the NSIS source (http://nsis.svn.sourceforge.net/viewvc/nsis/NSIS/trunk/Source/exehead/Ui.c?r1=4534&r2=4533&pathrev=4534) that at least sounds like it's referring to a similar problem:
// workaround for bug #1400995
//
// for an unexplained reason, MessageBox with MB_TOPMOST
// will fail, if no other messages were sent from this
// thread to the GUI thread before it.
//
// the source of the problem couldn't be found, so a
// WM_NULL is sent to work around it.
hmm, not able to reproduce it anymore using 2.2.1 and Vista
I can only reproduce it on windows xp - and I have a fix for it. Will commit tonight.
MessageBox is part of the Windows Common Controls - so we need to call: http://msdn.microsoft.com/en-us/library/bb775697%28VS.85%29.aspx prior to calling MessageBox. This is done behind the scenes (apparently) when creating a display.
Quote from: Matzon on December 02, 2009, 08:43:29
MessageBox is part of the Windows Common Controls - so we need to call: http://msdn.microsoft.com/en-us/library/bb775697%28VS.85%29.aspx prior to calling MessageBox. This is done behind the scenes (apparently) when creating a display.
That doesn't sound right to me. This C code works just fine without initing the common controls or creating any windows:
int main(int argc, char **argv)
{
MessageBox(0, "Blah", "Bleh", MB_OK);
}
Also, MessageBoxA/W are in User32.dll, not Comctl32.dll. And I'm quite sure that InitCommonControlsEX is not called behind the scenes when creating a normal window, otherwise there'd be no reason to call it in apps that use common controls.
be that as it may - adding the InitCommonControls call fixes the problem...
se also:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6582346
http://0memory.blogspot.com/2008/04/when-messagebox-in-initinstance-didnt.html
http://stackoverflow.com/questions/1383839/showing-dialogbox-and-messagebox-from-dll