SDL 2.0 Quit Event with Multiple Windows - event-handling

I'm using SDL 2.0, and decided to try out making multiple windows. Unfortunately, now I can't quit out of my program without going back to the IDE and force closing it.
The event handling is as simple as possible, I am only polling for the quit event, and it worked perfectly fine before I added the second window. Is the Quit Event ignored when using multiple windows? If so, how can I turn it back on?

The Quit Event is only sent when the last open window is trying to close, otherwise a window close event is sent.

I also ran into this problem, and the documentation is a little sparse on the topic so I ended up here.
The summary of the problem is:
If you have only one Window, clicking the X button will trigger an SDL_QUIT event.
If you have two or more windows, clicking the X button will trigger an SDL_WINDOWEVENT event, with an internal type of SDL_WINDOWEVENT_CLOSE.
So if your typical code for single-window quit events might look something like this:
SDL_Event e;
while (SDL_PollEvent(&e))
{
if (e.type == SDL_QUIT)
{
// ... Handle close ...
}
}
The multi-window equivalent would be:
SDL_Event e;
while (SDL_PollEvent(&e))
{
if (e.type == SDL_WINDOWEVENT
&& e.window.event == SDL_WINDOWEVENT_CLOSE)
{
// ... Handle window close for each window ...
// Note, you can also check e.window.windowID to check which
// of your windows the event came from.
// e.g.:
if (SDL_GetWindowID(myWindowA) == e.window.windowID)
{
// ... close window A ...
}
}
}
Note that on the last window, you will again receive SDL_QUIT because it's now the only active window - so best to structure your code in a way that correctly handles both depending on the circumstances.
See docs for more info.

Related

Stop VFP from showing dialog boxes when errors occur

I am trying to call an existing VFP 6 application using Jacob which is a COM bridge for Java.
val vfp = new Application(new ActiveXComponent("VisualFoxPro.Application").getProperty("Application").toDispatch())
vfp.setVisible(false)
try {
vfp.doCmd("do my.exe with myconfig.txt")
} catch {
case t: Throwable => t.printStackTrace
} finally {
vfp.doCmd("close data")
vfp.doCmd("clear all")
vfp.doCmd("clear")
vfp.quit
vfp.safeRelease
}
When there are no error conditions this code executes well and generates the expected .dbfs. The problem is that when an error occurs (.dbf not found, file in use by another user, etc) a GUI window pops up and stops execution of the program until I use the mouse to cancel it. I want this program to run on a server with no user interaction so this won't work.
How can I gracefully handle the errors preferably without making a change to the VFP 6 program?
Since you have the source code for VFP6, I would suggest looking into
SYS(2335,0)
Sys 2335 is used to identify if the program is running in an "unattended" mode, any such popup dialog boxes will throw an error and prevent an actual "hit" ok/cancel/whatever button to continue. This includes popup window prompting user to pick a table.
I'm not positive of when it was made available as I had limited use of it. Like you, when dealing with a COM server under IIS and obviously nobody there to respond.
Start JVM in headless mode, catch HeadlessException or something. Or, write a Java program that will execute your GUI program using Runtime, and restart in a case of parsed errors in console.

Can chrome.management.onInstalled.addListener alert extension A when extension B is installed?

Here's my code:
...
if($("input:checked").length > 0) {
chrome.tabs.create(
{url:"http://www.multiculturalyp.com/multiculturalypnewtab.crx"},
function(tab) {
chrome.management.onInstalled.addListener(function(info){alert("Installed A");});
chrome.management.onEnabled.addListener(function(info){alert("Enabled A");});
}
);
chrome.tabs.create(
{url:"instructions.html"},
function(tab) {
chrome.management.onInstalled.addListener(function(info){alert("Installed B");});
chrome.management.onEnabled.addListener(function(info){alert("Enabled B");});
}
);
}
...
So what is happening: I wrote an extension, and if a user so chooses from with that extension's options, a second extension is installed, so I launch instructions in the form of html to tell the user what to click if they really want it installed. I want to hide the instructions (close the instructions tab) automatically ones the second extension installs. The problem is that it appears that neither the onInstalled nor the onEnabled events are triggered. My example above is a simplified version of the logic that just alerts when the events are triggered but so far I can't get the onInstalled event for extension B to be triggered in extension A. I registered the events twice each when they didn't work the first time. The alerts end in A or B just to tell me whether the first registered listener, the second or both get triggered, but the should all get triggered in extension A.
So can this be done? If so, what am I doing wrong.
Thanks in advance.
My suggestion - try to bind events before executing a url with extension. Bind event once and check its type to make action (in the background page!):
chrome.management.onInstalled.addListener(function(info){
if(info.id == MY_EXTENSION_ID){
alert("Installed");
}
});
chrome.management.onEnabled.addListener(function(info){
if(info.id == MY_EXTENSION_ID){
alert("Enabled");
}
});
chrome.tabs.create({url:"http://www.multiculturalyp.com/multiculturalypnewtab.crx"},
function(tab) {alert('tab was opened')});

Messagebox.show fires twice after button click (MVVM)

I am using Galasoft MVVMLight. I have a button bound to a command which sends a message to the view to display a messagebox asking for confirmation. If I click either the Yes or No on the messagebox it performs the necessary actions then shows up again. However if I step through the program instead I only get the messagebox once. Is this a bug or is something else going on?
EDIT: I modified the messagebox.show line by adding an Icon and default result and now I can't reproduce this behavior... I'm stumped... if it happens again I'll try a counter like airplaneman19 suggested.
Try tracking the amount of times the MessageBox shows up with an integer, like so:
int counter = 0;
if(counter == 0){
MessageBox.Show();
counter++;
}
else if (counter == 1)
/*Do something that won't alter the program just to escape the if....else statement
like "x++";
I had a similar problem once, I mean, with MessageBox firing twice. It was due to focus changes, and ListView in WinForms fired another selection changed event when running the app; but when debugging - some focus change was missing, and there was no bug :)
I hope this atleast gives you some ideas...

Signal fires twice from gtkmm popup list

It's been a while since I used GTK+, and the last time I did was in C, not using gtkmm and C++ as I am now. Anyway, I have what I think should be an easy problem to solve:
I have a pop-up menu consisting of a list of radio buttons, and when I click one of them I want some action to occur. The code goes like this:
Gtk::RadioMenuItem::Group group;
for ( size_t i = 1; i < LH_MAX; ++i )
{
Gtk::RadioMenuItem* pItem = new Gtk::RadioMenuItem( group, names[i], names[i] );
pItem->set_name( names[i] );
pItem->signal_activate().connect( sigc::mem_fun(*this, &MyClass::on_item_activated) );
pItem->show();
m_Menu.append( *Gtk::manage(pItem) );
}
The only problem I see is that MyClass::on_item_activated gets called twice when a previously-unselected radio button is chosen from the menu. It's called only once when the already-selected radio button is clicked.
I'm guessing that the first firing is to say "something is no longer activate," and the second is for the new radio button activation. Whether I'm right or wrong, the question is the same: how best can I have my handler only take action once per click? Either I need the handler to get called only once, or I need something to check from inside it to know if the callback is a "duplicate" or not.
You could use sigc::bind to supply the item as a argument to the callback function.
pItem->signal_activate().sigc::bind(sigc::mem_fun(*this,&MyClass::on_item_activated),pItem));
Then you can use item->get_active() in the callback to respond to activations only.
void MyClass::on_item_activated(Gtk::RadioMenuItem* item) {
if (item->get_active()) {
// Do some stuff
}
}
That's what I do too, connect to signal_toggled() and check if get_active() is true.
I don't know exactly what you're trying to accomplish (or what MyClass is and what base classes it inherits from), but connecting to signal_toggled() might be more useful than signal_activate()
/Agree with Johannes. Check if the item is activated when receiving the signal.

WMI and Win32_DeviceChangeEvent - Wrong event type returned?

I am trying to register to a "Device added/ Device removed" event using WMI. When I say device - I mean something in the lines of a Disk-On-Key or any other device that has files on it which I can access...
I am registering to the event, and the event is raised, but the EventType propery is different from the one I am expecting to see.
The documentation (MSDN) states : 1- config change, 2- Device added, 3-Device removed 4- Docking. For some reason I always get a value of 1.
Any ideas ?
Here's sample code :
public class WMIReceiveEvent
{
public WMIReceiveEvent()
{
try
{
WqlEventQuery query = new WqlEventQuery(
"SELECT * FROM Win32_DeviceChangeEvent");
ManagementEventWatcher watcher = new ManagementEventWatcher(query);
Console.WriteLine("Waiting for an event...");
watcher.EventArrived +=
new EventArrivedEventHandler(
HandleEvent);
// Start listening for events
watcher.Start();
// Do something while waiting for events
System.Threading.Thread.Sleep(10000);
// Stop listening for events
watcher.Stop();
return;
}
catch(ManagementException err)
{
MessageBox.Show("An error occurred while trying to receive an event: " + err.Message);
}
}
private void HandleEvent(object sender,
EventArrivedEventArgs e)
{
Console.WriteLine(e.NewEvent.GetPropertyValue["EventType"]);
}
public static void Main()
{
WMIReceiveEvent receiveEvent = new WMIReceiveEvent();
return;
}
}
Well, I couldn't find the code. Tried on my old RAC account, nothing. Nothing in my old backups. Go figure. But I tried to work out how I did it, and I think this is the correct sequence (I based a lot of it on this article):
Get all drive letters and cache
them.
Wait for the WM_DEVICECHANGE
message, and start a timer with a
timeout of 1 second (this is done to
avoid a lot of spurious
WM_DEVICECHANGE messages that start
as start as soon as you insert the
USB key/other device and only end
when the drive is "settled").
Compare the drive letters with the
old cache and detect the new ones.
Get device information for those.
I know there are other methods, but that proved to be the only one that would work consistently in different versions of windows, and we needed that as my client used the ActiveX control on a webpage that uploaded images from any kind of device you inserted (I think they produced some kind of printing kiosk).
Oh! Yup, I've been through that, but using the raw Windows API calls some time ago, while developing an ActiveX control that detected the insertion of any kind of media. I'll try to unearth the code from my backups and see if I can tell you how I solved it. I'll subscribe to the RSS just in case somebody gets there first.
Well,
u can try win32_logical disk class and bind it to the __Instancecreationevent.
You can easily get the required info
I tried this on my system and I eventually get the right code. It just takes a while. I get a dozen or so events, and one of them is the device connect code.