|
I think you'll find you can only use a DC on the same thread on which the window was created. In general, the best method is to share the data with a UI thread, which will then draw it.
Max++ wrote: The read data from each sensors is so fast(less than millisecond) So,I separate 4 thread for draw graph in each sensor.
Can you define what you mean by 'fast (less than millisecond)'? If you mean 'updates every millisecond, then you're not going to have too much luck just collecting it in threads in Windows - Windows isn't designed for those sorts of response times - unlike an RTOS.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
Google for "mtgdi sample".
It is a crappy thing, but it's life -^ Carlo Pallini
|
|
|
|
|
As Stuart said you should only use a DC from the same thread as the window was created.
But I consider that a minor problem as I believe that you don't need multiple threads for drawing the graphs. Read on...
I've written quite a few (>25) applications with similar functionality, so perhaps I can contribute with some thoughts.
You have to distinguish between the different layers in your application.
You have at least three layers here that should not be mixed up: the hardware layer, the data acquisition layer and the presentation layer.
Max++ wrote: The read data from each sensors is so fast(less than millisecond) So,I separate 4 thread for draw graph in each sensor.
Here's the mix up.
Even though your sensors can barf up measured data at that rate, it doesn't necessarily mean that the data should be presented to the user at the same rate, or in other words "in real-time". There's no point since the human eye cannot cope with that speed.
You need to think about the requirements of your application; shall it e.g. be possible to save the sampled data and what is the sample frequency, or is it just for presentation?
Perhaps the data acquisition layer should save every sample, but the presentation layer only need to ask for the current value of each sensor at e.g. 2Hz rate.
You have to tell us more about the requirements of your application for us to be able to suggest a suitable design.
But, based on my experience of common demands for such an application, I would suggest to have the following in mind:
- The main (UI) thread is responsible for drawing all the graphs that are supposed to be presented to the user and would update the graphs on timer based events with rather low frequency, e.g. 2Hz to 5Hz. This would be the presentation layer.
- The hardware layer continuously issues read requests in a "reading worker thread" with calls to
::ReadFile() that will return one or more data samples. They should probably be put in a queue from which the data acquisition layer can read them. In order to prevent immense memory allocation and deallocation I suggest using reference counting smart pointers as elements of the container. - If the gathered data needs some kind of interpretation, each sensor could have a thread that collects the data and save it in e.g. list in order to be able to save it later. When this thread runs it moves the data from the queue shared with the hardware layer into the its own container and updates the "current value" shared with the presentation layer. This would be the data acquisition layer.
If the raw data can be used for presentation you can omit the data acquisition layer and simply read the top element of the queue, or list, for each sensor that the "reading worker thread" puts the data in.
This way you have a clean design, you don't do any unnecessary updates to the GUI and you're able to save every data sample gathered from each of your sensors.
Sometimes the samples should be tagged with the time that it was sampled, but that depends on the requirements.
"It's supposed to be hard, otherwise anybody could do it!" - selfquote "High speed never compensates for wrong direction!" - unknown
|
|
|
|
|
Thanks a lot Roger.
Your answer and solution very useful for me and also difficult for me to finish it.
Actually, my sensor is A/D concept that some time need to measure AC voltage
and show the data in real time, look like oscilloscope.
if you have some link, book or example for this concept.
Please advise me.
Thanks
|
|
|
|
|
Max++ wrote: measure AC voltage
and show the data in real time, look like oscilloscope.
I'm suspicious about this requirement.
If you have an oscilloscope, connect it to an AC signal and let it run freely as in "real-time", all you'll see is a blur. To have it make sense you'd have to use the trigger functionality.
You have to describe what the purpose is, as in "what will the user do with the graphs presented in front of him". My point is that you probably won't need to present every sample to the user as soon as it arrives.
If this is for e.g. signal calibration it would probably do quite well if the graphs were updated twice per second. Perhaps every sample should presented in that case, but you can disregard from the "real-time" problem.
Max++ wrote: if you have some link, book or example for this concept.
Regarding how to call ::ReadFile() and how get the data, you may find this article[^] to be useful. It's about serial port programming, but the concept of reading is the same.
"It's supposed to be hard, otherwise anybody could do it!" - selfquote "High speed never compensates for wrong direction!" - unknown
|
|
|
|
|
if the data update every 1 millisecond.I get data and move it to some variable, after finish 1000 data I draw graph one time.That mean draw every 1 second.
Can you tell me, Is this oscilloscope concept?
|
|
|
|
|
Max++ wrote: if the data update every 1 millisecond.I get data and move it to some variable, after finish 1000 data I draw graph one time......Is this oscilloscope concept?
Well, 'yes' and 'no'.
You can configure an oscilloscope to behave similarly (depending on the model of course).
But you can also configure an oscilloscope to behave differently, it all depends on how you want to display the measured values in order to analyse them.
If this is suitable for the purpose of your application, go ahead and implement it. You have at least removed your problem about all threads with different DCs drawing to the same window, which was your original issue.
If you need a more specific answer you have to describe how your application is supposed to be used and for what purpose.
"It's supposed to be hard, otherwise anybody could do it!" - selfquote "High speed never compensates for wrong direction!" - unknown
|
|
|
|
|
As I mention that I have 4 sensor in my project including temperature, Humidity, voltage and current.
All one is encoded with FPGA from outside and then send the data through USB port.
My application's job is that get the data from USB and decode for separate data of each sensor, keep it to database and show the result on monitor.
For the temperature and humidity the data update every second these is not the the problem.
The problem for now is voltage and current sensor that update every 10uS and 20uS respectively.I have to keep it to database and also show data in real time on monitor.
The graph that application draw should according to the voltage that sensor get such as the sensor is measuring sine wave voltage, so on monitor should show sine wave too.
The concept look like oscilloscope but the different is my application show only image no need to calculate the amplitude and frequency.
Can you suggest the best way to manage these data.
|
|
|
|
|
I have an MFC dialog base application.
It uses NetFileEnum to get the all open files.
NetFileEnum() returned NERR_Success, but the bufptr is NULL. Also when I checked the GetLastError(), it returned 997( Overlapped I/O operation is in progress. )
OS: Windows XP SP2
Installed: Platform SDK2003
PFILE_INFO_3 pBuffer;
PFILE_INFO_3 pCurrent;
DWORD dwEntriesread = 0;
DWORD dwTotalentries = 0;
DWORD dwStatus = NetFileEnum( NULL,NULL,NULL,3,( LPBYTE* )&pBuffer,MAX_PREFERRED_LENGTH,&dwEntriesread,&dwTotalentries, NULL );
Could you please tell me y this error?
aks
|
|
|
|
|
aks. wrote: NetFileEnum() returned NERR_Success, but the bufptr is NULL.
What is the value of dwEntriesread and dwTotalentries ?
"Old age is like a bank account. You withdraw later in life what you have deposited along the way." - Unknown
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
|
|
|
|
|
Hi,
I have created slider bar dynamically using create function. now i want to create one integer control for the slider bar.
Can any one help me how to create DDX control for the slider bar..
I have added DDX control in DoDataExchange function like this:-
DDX_Slider(pDX,IDC_SLIDER1, m_Pos);
but the app is crashing..
Can any one help me regarding this..?
Any help will be appriciated..
Thanks
Venki
|
|
|
|
|
Does it crash or does it raise a debug assertion? If it is the later, check where the assert comes from, there are useful hints about problems as comments in the MFC code...
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Life: great graphics, but the gameplay sux. <
|
|
|
|
|
Hi Code-o-mat,
i am getting below error in the debugging state..
TRACE1("Error: no data exchange control with ID 0x%04X.\n", nIDC);
along with this i am getting other error :-
"An unsupported operation was attempted"
can you please let me know what i can do now..?
Thanks
Venki
|
|
|
|
|
Well, what this generally means is that it did not find any control with that id (IDC_SLIDER1) on the dialog. Are you sure that is the ID you gave to your dynamically created slider? And are you sure you placed the DDX_Slider entry in the class of the correct dialog?
Also, are you sure you created your slider BEFORE DoDataExchange runs? If you did something like this:
BOOL CMyDialog::OnInitDialog()
{
__super::OnInitDialog();
m_mySlider.Create(...)
...
That won't work since during the __super::OnInitDialog() call your DoDataExchange will be fired...so instead, do it like:
BOOL CMyDialog::OnInitDialog()
{
m_mySlider.Create(...)
__super::OnInitDialog();
...
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Life: great graphics, but the gameplay sux. <
|
|
|
|
|
Hi Code-o-mat,
I am able to solve the problem with the help of your tip, thank you so much for your help.
I have one more small doubt, i have created pointer object for the CSliderCtrl like this: CSliderCtrl *track_bar;
trakbar = new CSliderCtrl;
Can't we create normal object instead of pointer object..? if there is any way to create that please kindly let me know..
Thanks
Venki
|
|
|
|
|
Why don't you simply create a member of your dialog class of type CSliderCtrl? Like this:
class CMyDialog: public CDialog
{
...
CSliderCtrl m_myPreciousSlider;
...
};
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Life: great graphics, but the gameplay sux. <
|
|
|
|
|
Hi,
I'm trying to intercept the copy/move operation between two explorer windows, but can't seem to know how to do this.. i already try to implement a shell extension with no success and now i'm turning to hook the explorer process.. but with no success too.
The idea is simple, when a user drags a file from a explorer folder into another explorer or another explorer folder, my code will verify the file contents and if desired cancel the copy/move operation.
Can anyone point me to a solution on how to accomplish this?
Thanks
Nuno
Nuno
|
|
|
|
|
|
I have not found this interface yet and i'm not sure what this thing does.. i will give a look at it and see what it does..
Thanks
Nuno
|
|
|
|
|
Did you include shlobj.h?
BTW, this interface is deprecated in Windows Vista.
-Sarath.
"Great hopes make everything great possible" - Benjamin Franklin
|
|
|
|
|
What did you try to hook?
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Life: great graphics, but the gameplay sux. <
|
|
|
|
|
nothing really... I'm yet trying to figure how the all thing works.. if you have any suggestion please do tell that i really appreciate. (i'm seeing some codeproject articles on the subject)
Nuno
Nuno
|
|
|
|
|
Well, i would try hooking DoDragDrop[^], if you are lucky, explorer uses that method to perform the drag-drop, this method, as the documentation says, gets an IDataObject[^] and an IDropSource[^] pointer, maybe you could use these to analyze what is being dragged. Finding out where the data is being dragged to could pose a problem though...
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Life: great graphics, but the gameplay sux. <
|
|
|
|
|
Hi, thanks for the suggestion, but the DoDragDrop is only called on the begining of the drag and drop process. And i will never known where is the source and if is a move or copy operation.
I tried to hook the SHFileOperationW and i can get all the things that i needed, but the problem is that the FO_DELETE operation allways crash the explorer process, even if i don't have any code inside my hook function implementation:
int MySHFileOperation(LPSHFILEOPSTRUCT lpFileOp)
{
VirtualProtect((LPVOID)pOrigSHFOPAddress, SIZE, myProtect, NULL); //ReadWrite again
memcpy(pOrigSHFOPAddress, oldBytes, SIZE); //Unhook API
int nRes = SHFileOperation(lpFileOp);
memcpy(pOrigSHFOPAddress, JMP, SIZE); //Rehook API
VirtualProtect((LPVOID)pOrigSHFOPAddress, SIZE, oldProtect, NULL); //Normal setts
return nRes;
}
PS: i used the technique described by AlexAbramov in "API Hooking with MS Detours" without the detours
I think i will try another approach for my problem... there are a few problems with the hook approach, one is that the SHFileOperation is deprecated in vista, and another i think that this approach is a little unorthodox..
So i will try to find another way of doing this, if anyone has some better suggestion please feel free to post it
Thanks
Nuno
|
|
|
|
|
Hi everybody
in my application i open a view to display the "products information"
In this view i have a TabControl within 3 Views.
Each of these Views has more than 100 controls (labels with textboxes)
So over 350 controls totally.
If i open this window i freeze the Desktop-Screen
and at the last execution point of my code, i release the Screen and redraw.
I measured the elapsed time for all the work to show this window.
It takes 0,3 seconds.
If i remove all controls from the views, i get a time less than 0,1 seconds.
Is there a possibility to speed up the traitment ( < 0,3seconds )
If not, why does it take exactly so long?
Big thanks for any information.
|
|
|
|
|