I've a problem with GIFs in my Delphi project (I'm using Delphi 10.4 Sydney). I'm not able to stop GIF after one execution.
I don't want to loop endlessly.
I've tried this:
frameGif := (Image1.Picture.Graphic as TGIFImage);
frameGif.AnimateLoop := false;
frameGif.Animate := true;
GIF doesn't stop after one execution.
I've found these solutions:
Can we stop animate in TGIFImage delphi component?
TGIFImage with animated GIF - events are not working - how to detect animation progress?
Is TGIFRenderer approach still only way?
How can I use OnLoop event (if I must) when I create GIFs programmatically during program execution?
Best regards....
Related
Backstory:
I want to write a C program to automate clicks in a program running in OSx (in a desktop setting).
I first tried Using Quartz Event Services to simulate input events. But then I had this problem: Simulating mouse clicks on Mac OS X does not work for some applications, and the answers didn't help in my case.
CGEventRef click1_down = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseDown, CGPointMake(posx, posy), kCGMouseButtonLeft);
CGEventSetIntegerValueField(click1_down, kCGMouseEventClickState, 0);
// This down click works about 5% of the time.
CGEventPost(kCGHIDEventTap, click1_down);
usleep(30000);
CGEventRef click1_up = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseUp, CGPointMake(posx, posy), kCGMouseButtonLeft);
CGEventSetIntegerValueField(click1_up, kCGMouseEventClickState, 1);
CGEventPost(kCGHIDEventTap, click1_up);
// I've tried every combination of CGEventSetIntegerValueField, usleep and CFRelease, nothing seems to help
// The only thing helping is repeating the line: "CGEventPost(kCGHIDEventTap, click1_down);" 100s of times,
// then the down click works about 80% of the time, still not acceptable
I'm now turning to solution #3 suggested here: How can Mac OS X games receive low-level keyboard input events?
(this might also help How can I simulate the touch events by IOHIDEvent?)
I tried with Karabiner by sending a mouse click on key press:
<item>
<name>Right Mousebutton</name>
<identifier>rightMouseButton</identifier>
<autogen>__KeyToKey__ KeyCode::H, PointingButton::LEFT</autogen>
</item>
And this sends the click 100% of the time, but I want to send the click with by writing C code (to have greater control). Tough I'm not sure, Karabiner seems to use IOKit to send events, so I think this should work in my case, if I'm able to send mouse events with IOKit.
So my question is basically: how do I write a C program to simulate a mouse left click with IOKit ? The documentation is very sparse and I didn't manage to do it.
I tried getting inspiration from some projects:
https://github.com/tekezo/Karabiner
https://github.com/NoobsArePeople2/manymouse
Almost every tutorial I find tells me to do this for my event loop:
XEvent event;
while (true)
{
XNextEvent(display, &event);
switch (event.type)
{
case Expose:
printf("Expose\n");
break;
default:
break;
}
}
However, clicking the X to close the program results in this message.
XIO: fatal IO error 11 (Resource temporarily unavailable) on X server ":0"
after 10 requests (10 known processed) with 0 events remaining.
It is indeed strange to me that the examples suggest using an infinite loop. That doesn't sound natural, and my other X11 programs don't do that. So I searched around. I found out how to capture the window close event.
Atom wmDeleteMessage = XInternAtom(mDisplay, "WM_DELETE_WINDOW", False);
XSetWMProtocols(display, window, &wmDeleteMessage, 1);
XEvent event;
bool running = true;
while (running)
{
XNextEvent(display, &event);
switch (event.type)
{
case Expose:
printf("Expose\n");
break;
case ClientMessage:
if (event.xclient.data.l[0] == wmDeleteMessage)
running = false;
break;
default:
break;
}
}
That works. It exits without errors. ... But I refuse to believe this is the normal way to do things. I mean, is this the only way to properly exit an X11 app? It seems like a lot of work just to capture the close event. How do I make a 'proper' event loop? Why is the close event so deeply buried? What am I missing?
The problem lays in the communication between X Server and the Window Manager.
When you call XCreateWindow or XCreateSimpleWindow, the X Server creates your window (not showing it until you explicitly map it on the screen by calling XMapWindow), and then the Window Manager is responsible for attaching all the decorations and buttons and system menu around your window.
You can call XDestroyWindow on your own to remove the window, and this usually means it just disappears from the screen, but your program is still running and the connection to the X Server is still open, so you can send it some more requests.
The problem begins when the user clicks that little X button attached to your window by the Window Manager, because it is not created by the X Server and it is not his business to decide what to do then. Now it's all in hands of Window Manager.
If the Window Manager simply called XDestroyWindow on your window, it would cause a problem if your application wanted to capture the closing event to do something before the window gets destroyed. So the convention has been established between the X Server and the Window Managers to handle this process.
The default behavior of most Window Managers is to destroy the window and close the connection with the X server, because this is what most users of Window Managers would expect: that when they close the window, the program will end (and the connection to the X Server will close with the closed window). And then, when you try to call XCloseDisplay(display), it will cause the IO error you've mentioned, because the connection to the server is already closed and the display structure is invalid.
Here's an excerpt from the Xlib documentation which explains this:
Clients that choose not to include WM_DELETE_WINDOW in the WM_PROTOCOLS property may be disconnected from the server if the user asks for one of the client's top-level windows to be deleted.
Yeah, it would be great if they didn't hide it so deep in their docs, though :-P
But when you already find it, fortunately it also hints for the solution.
If you want a different behavior (that is, to capture the closing event from the Window Manager), you need to use the WM_DESTROY_WINDOW protocol.
Another excerpt from the docs:
Clients, usually those with multiple top-level windows, whose server connection must survive the deletion of some of their top-level windows, should include the atom WM_DELETE_WINDOW in the WM_PROTOCOLS property on each such window. They will receive a ClientMessage event as described above whose data[0] field is WM_DELETE_WINDOW.
I had the same error and I wanted to know exactly what causes it and why. It took me some time to figure it out and find the proper explanation in the doc, so I put my explanation here to save the time of others uninformed.
There are no such things as "exit button" or "application" or "close event" in X11. This is by design.
Window decorations, exit buttons and many the other things we depend upon are not built into X11. They are implemented on top of the core X11 instead. The name of the particular set of conventions responsible for wmDeleteMessage is ICCCM, look it up.
Xlib only deals with the core X11 protocol. No built-in close event there.
There are toolkits that make dealing with ICCCM and all other things that are not built into X11 easier (GTK, wxWindows, Qt, ...) You probably want to use one of those.
My silverlight code:
var stream = TitleContainer.OpenStream("Giggle.wav");
var effect = SoundEffect.FromStream(stream);
FrameworkDispatcher.Update();
effect.Play();
The file, Giggle.wav plays multiple times. I expected the code would wait while the "Play" method executes.
Suggestions to make it play one instance at a time?
Thanks
How about DynamicSoundEffectInstance? Play your sound and when BufferNeeded event occurs - play next one. I am not sure but I think I saw another way how to play a sound synchronously. When I will find I will let you know.
Hey I am trying to make a GTK IRC client that uses webkit to display its messages.
The webview is within a ScrolledWindow, and I want the scrolledwindow to scroll to the bottom everytime it gets too big.
I've tried changing the vadjustment value of the scrolledwindow when a message is added but this doesn't seem to work at all. It keeps reseting it to 0 for some reason.
Does anyone know how I might solve this?
Cheers!
I had this same problem. I believe the issue is caused because the adjustment-changed and adjustment-value-changed signals not always sent after the window has completely finished redrawing. This causes the adjustment value to be zero because the page has no content at that point. The solution is to connect to the size-allocate signal instead. This is only called when the window has completely finished resizing, and has the extra advantage of not being called when the user scrolls the window manually.
Here is a sample using python bindings:
def autoscroll_view(view, allocation):
#parent is the gtk.ScrolledWindow that needs updating
parent = view.get_parent()
adj = parent.get_vadjustment()
adj.value = adj.upper - adj.page_size
parent.set_vadjustment(adj)
view = webkit.WebView()
window = gtk.ScrolledWindow()
window.add(view)
view.connect('size-allocate', autoscroll_view)
I'm attempting to use a large number of short sound samples in a game I'm creating in Silverlight 2. The samples are less than 2 seconds long.
I would prefer to load all the audio samples onto the canvas during the initualization. I have been adding the media element to the canvas and a generic list to manage it. So far, it appears to work.
When I play the sample the first time, it plays perfectly. If it has finished playing and I want to re-use the same element, it cuts off the first part of the sound. To play the sample again, I stop and play the media element.
Is there another method I should use the samples so that the audio is not clipped and good performance is obtained?
Also, it's probably a good idea to make sure that all of your audio samples are brought down to the client side initially. Depending on how you set it up, it's possible that the MediaElements are using their progressive download functionality to get the media files from the server. While there's nothing wrong with this per se (browser caching should be helping you out after the initial download), it does mean that you have to deal with the browser cache, and there are some potential issues there.
Possible steps to try:
Mark your audio files as "Content". This will get them balled up in the .xap.
Load your audio files into MemoryStreams (see Application.GetResourceStream method) and call MediaElement.SetSource().
HTH,
Erik
Some comments:
From MSDN:
Try to limit the number of MediaElement objects you have in your application at once. If you have over one hundred MediaElement objects in your application tree, regardless of whether they are playing concurrently or not, MediaFailed events may be raised. The way to work around this is to add MediaElement objects to the tree as they are needed and remove them when they are not.
You could try to seek to the start of the sample to reset the point currently being played before re-using it with:
mediaelement.Position = new TimeSpan();
See also MSDNs MediaElement.Position.
One techique you can use, although I'm not sure how well it will work in Silverlight, is create one large file with all of your samples joined together (probably with a half-second or so of silence between each). Figure out the timecode for each sample and seek the media element to that position and play. You'll only need as many media elements as simultaneous sounds you want to play.