I have a small application that needs to update GUI elements if some event occurs in lower levels, say, socket goes off-line, or something like that.
In Windows, I could use PostMessage which would be sent through the chain to all Windows, and the required ones could update accordingly.
How can I achieve something similar in wxWidgets? I cannot use OnUpdateUI, or something like that, because some controls doesn't seem to handle that at all.
The target window could be one or multiple, they could be frames or controls, so I'm confused a little here.
Does anyone have a suggestion?
First, all controls do receive EVT_UPDATE_UI so you could use it for this and it's a very simple of doing it -- but also the most inefficient, so definitely not recommended for something like socket event processing (it's fine for checking whether the socket is connected or not though).
Second, the exact equivalent of Windows ::PostMessage() is wxQueueEvent() (which used to be called as wxPostEvent() actually but the new version is preferable). wxQueueEvent() is thread-safe in the sense that it can be used from a secondary thread to post an event to a GUI control managed by the main thread.
You can use the same approach as in Win32 apps. You can create the custom event class and send it to windows using wxPostEvent function. There are some docs regarding this.
Not sure what you mean about wxUpdateUIEvent - from my experience it works pretty fine. What controls do not receive it? Did you add EVT_UPDATE_UI() macro to event table?
Related
I would like to create a wxPython app such that:
If I run a second instance of that app (e.g., call the Python script from the shell a second time), no new instance should be created.
Instead, the toplevel frame of the already running instance should be raised and focussed.
The first point can be easily implemented by wx.SingleInstanceChecker (see the example code there), but at least the example code only gives a way for making the second instance of the app abort, but not raise the existing app's main frame.
I am using wxPython-Phoenix with Python 3.
Claritication: I would much prefer an out-of-the-box solution like wx.SingleInstanceChecker (that is, not implement my own locking and IPC solution).
You can use any kind of IPC to send a message asking the other program to do whatever needs to be done (just raise its top level window or maybe handle the command line options passed to the second instance). In C++ there are wxConnection and the related wxServer and wxClient classes that can be used for this, but I'm not sure if they're wrapped by wxPython -- however you could use any Python IPC module instead, if they aren't.
As has been pointed out, the "correct" way to do this is IPC because you have a new process that is supposed to affect a change (raise and focus) in another process.
What you seem to want is to take advantage of the IPC channel that wx.SingleInstanceChecker is already using to do your work. Unfortunately, you can't. That class is implemented in the wxWidgets c++ code and therefore there are no Python bindings to the internal workings of the class.
However, you can probably abuse wx.SingleInstanceChecker to do what you want. In your program, you can set up a timer at some rapid interval (say, 250ms) that will constantly check IsAnotherRunning() from your main process. Therefore, when your second process starts up, the first will notice and can raise itself to the front. You would just have to wait for a little bit in the secondary process before it exits, to give the first time to notice.
I'm becoming mad trying to figure out how to resolve this task. My goal is pretty easy, copy a file on the USB stick every time that it is inserted and then release the USB stick turning off the LED. What is the best way to solve it?
1) I found this article
http://geekswithblogs.net/BruceEitman/archive/2008/06/13/windows-ce-monitoring-for-disk-insertion-to-add-support-for.aspx
or
http://geekswithblogs.net/BruceEitman/archive/2008/06/13/windows-ce-monitoring-for-disk-insertion-to-add-support-for.aspx
but I can't translate it on VB.NET project.
2) Then I read that is enough to use RequestDeviceNotifications for block devices. But How can I do that in VB.NET?
I would like to avoid OpenNetCF if possible.
Thank you
Since you don't want to "use OpenNETCF" I assume that you don't want to use any libraries or capabilities not built in to the CF. We'll skip the argument of that silliness and the "value of your time" discussion and take that as a requirement.
What you need to do is:
Use P/Invoke to call CreateMsgQueue. That's going to give you back a Handle. You'll probably want to do CloseMsgQueue as well for completeness
P/Invoke RequestDeviceNotifications and pass it the handle returned from #1 above along with the DEVCLASS GUID value for the device notifications you want - probably STORE_MOUNT_GUID. Again, adding StopDeviceNotifications for completeness is a good idea.
At that point you'll get a message on the queue whenever a insert or remove happens. You then call ReadMsgQueue to get the DEVDETAIL data in the message.
Parse the DEVDETAIL and look at the fAttached member.
It'd take me a while to write that for you, so you'll need to do this on your own.
Start writing the project, find P/Invoke routines for the calls you need (like FindFirstFile and CreateProcess). On SO, have a look at Storage Card Problem In windows mobile and How to register form for WM_DEVICECHANGE message in windows mobile.
You are only going to be dead in the water if you can not find a particular call that you can't make.
As you work through your project, post (or search for) the actual problems you run into.
Otherwise, it sounds like you are asking someone to write the project and hand it to you.
Sometimes when looking at someone else's large Objective-C program, it is hard to know where to begin.
In such situations, I think it would be helpful to log every call to every non-Apple method.
Is there a way to do that? Basically, make one change in some central place, and log every method that is called. Preferably limited to non-Apple methods.
You can set the environment variable NSObjCMessageLoggingEnabled to YES. This will write a log of all message sends in the folder /tmp/msgSends-xxx.
You could add a symbolic breakpoint to objc_msgSend(), and have it log the second parameter without stopping.
How to do it for your own methods only though is a toucher task. Maybe if you could inspect the class name being called and do some magic to have a conditional breakpoint for only calls where the class' prefix matches your own?
I don't think logging every single call is practical enough to be useful, but here's a suggestion in that direction.
On a side note, if it's a large program, it better have some kind of documentation or an intro comment for people to get started with the code.
In any case, every Cocoa application has an applicationDidFinishLaunching... method. It's a good place to start from. Some apps also have their principal (or 'main window') class defined in the Info.plist file. Both these things might give you a hint as to what classes (specifically, view controllers) are the most prominent ones and what methods are likely to have long stack-traces while the program is running. Like a game-loop in a game engine, or some other frequently called method. By placing a breakpoint inside such a method and looking at the stack-trace in the debugger, you can get a general idea of what's going on.
If it's a UI-heavy app, looking at its NIB files and classes used in them may also help identify parts of app's functionality you might be looking for.
Another option is to fire up the Time Profiler instrument and check both Hide missing symbols and Hide system libraries checkboxes. This will give you not only a bird's eye view on the methods being called inside the program, but also will pin-point the most often called ones.
By interacting with your program with the Time Profiler recording on, you could also identify different parts of the program's functionality and correlate them with your actions pretty easily.
Instruments allows you to build your own "instruments", which are really just DTrace scripts in disguise. Use the menu option Instrument >> Build New Instrument and select options like which library you'd like to trace, what you'd like to record when you hit particular functions, etc. Go wild!
That's an interesting question. The answer would be more interesting if the solution supported multiple execution threads and there were some sort of call timeline that could report the activity over time (maybe especially with user events plotted in somehow).
I usually fire up the debugger, set a breakpoint at the main entry point (e.g. - applicationDidFinishLaunching:withOptions:) and walk it in the debugger.
On OSX, there are also some command-line tools (e.g. sample and heap) that can provide some insight.
It seems like some kind of integration with instruments could be really cool, but I am not aware of something that does exactly what you're wanting (and I want it now too after thinking about it).
If one were to log a thread number, and call address, and some frame details, it seems like the pieces would be there to plot the call timeline. The logic for figuring out the appropriate library (Apple-provided or third party) should exist in Apple's symbolicatecrash script.
VB.NET, .NET 4
Hello all,
I have an application that controls an industrial system. It has a GUI which, once a process is started, principally displays the states of various attached devices. It basically works like this:
A System.Timers.Timer object is always running. At each Elapsed event, it polls the devices for their current values and invokes controls on the GUI, updating them with the new values.
A start button is clicked, a process time Stopwatch object is created and started (Labels on the GUI are now invoked and updated on the System.Timers.Timer's Elapsed event, in addition to the other work that is taken care of on this event)
A new thread is created which runs a Process() subroutine
Some Stopwatch objects are created and started (these Stopwatches are periodically restarted during the process via their Restart() method.
Some logic is executed on the new Stopwatchs' Elapsedmilliseconds properties to determine when to do things like write new setpoints to the devices, update the data log, etc...
Here's my problem: The program occasionally freezes. My ignorant efforts at tracking down the problem have led me to suspect that read/writes to the subset of devices that are RS-232 controlled are the culprits most of the time. However, I occasionally see other strange things upon program freeze, e.g., one of the time Labels whose Text property is determined by a Stopwatch's Elapsedmilliseconds property sometimes will show an impossible value (e.g., -50 hours or something).
For the RS-232 problems, I suspect something like a read event is being executed at the same time as a write event and this causes a freeze(?). I tried to prevent this by making sure that all communication with an RS-232 device is funneled through a Transmit() subroutine which has the following attribute:
Which, as far as my ignorance permits me to understand, should force one Transmit() execution to finish completely before another one can start. Perhaps another risk is the code getting blocked here if one Transmit() never finishes?
Regarding the Stopwatch trouble, I speculate that the problem is that the Timer is trying to update a GUI Label at the same time that the Stopwatch's Restart() method is being executed. I'm unsure if this could cause a problem. All I know is that this problem has only occurred at a point in the process when a Restart() call would be made.
I am wondering if I could use a SyncLock or something to lock a Stopwatch while the Label is being updated (or, conversely, while its being restarted)? Or, perhaps I should stop the Timer, restart the Stopwatch, and then start the timer again, like so?:
Timer.Stop
Stopwatch.Restart
Timer.Start
My trepidation regarding how to proceed is due to my complete lack of understanding of how .NET synchronization objects actually work. I've tried slapping a few SyncLocks in various places, but I really have no idea if they're implemented correctly or not. I'm wondering if, having provided all this context, someone really smart might be able to tell me how I'm stupid and how to do this right. I would really appreciate any input. If it would be useful to provide some code snippets, I'd be happy to, I just worry that everything's so convoluted that it would just detract from what I'm hoping is a conceptual question.
Thanks in advance!
Brian
I would consider a shift to a task scheduling framework instead of relying on manual manipulation of timers if your working on anything SCADA related. A simple starting point would be something similar to the hardcodet.Scheduling classes and you can move to something like the beast that is Quartz. Most of these types of frameworks will provide you with a way to pause and resume scheduled actions.
If I'm working with Modbus, I normally keep a local cache of the register values and make changes to any value fire a change event. This has the benefit of allowing you to implement things like refreshing values manually without interfering with your process scheduling and checking for deadband when evaluating your polled response. This happened to be the side effect of implementing a polled protocol to a subset of the OPC DA interface.
A simple application is written in CF 2.0. It's single-threaded as far as I'm concerned.
Two parts of the application are of interest: an event handler that handles "Barcode scanned" event raised by a class that represents PDA's barcode scanner (provided by manufacturer), and an event handler for Windows.Forms.Timer that runs every 30 seconds.
Recently the application suffered from a bug the only possible reason for which, as I can see, is processing Barcode Scanned event right in the middle of Timer_Tick event. I was absolutely sure that this was not possible and that one of the events would wait in the queue until first one is handled completely. Windows.Forms.Timer page in MSDN also assures that it's a regular single-threaded timer. Code triggered by Barcode Scanned changes some pieces of the interface, that causes no exceptions, so I'm assuming it's single-threaded as well. No, we're not using DoEvents or such.
Can anybody tell me for sure that such reentrancy is not possible and I should look harder for other possible reasons, or vice versa, that they have suffered from the same problem?
The Windows.Forms timer is going to happen on the UI thread via a call to PostMessage. That is a guarantee. How the "barcode scanned" even comes in is completely up to the developer of the library that's giving you the event. You should certainly not assume that it's going to run in the same context as your timer unless you specifically force it to (via a call to Control.Invoke). Even with that I don't believe you can guaranteee a call order.
If you think re-entrancy might be a cause, the solution is relatively simply - use a Monitor in both handlers (the timer proc and the event) and lock on the same object. That will rule out the possibility that it's a reentrancy issue. If the problem goes away, you know the cause and already have a fix. If the problem persists then you know for certain that it's not reentrancy and you can focus elsewhere.
Pretty much every barcode scanning component i've worked with runs off a background thread, so i'd look at that more closely.