|
Hi,
I have implemented using OnTimer function in which I will close the dialog after some specified time.
Now I have one issue.....I am displaying a message box that "operation completed.!" when the process completes.
I have CANCEL button on the dialog box.....
When user clicks the cancel button, I am closing and terminating the process. Now I don't want to display the message box when user has clicked the cancel button on the dialog.
I am doing like this.
CProgressDlg progDlg;
progDlg.SetPurpose(_T("Video, Please Wait........"));
if(progDlg.DoModal() == IDCANCEL)
{
WaitForSingleObject(pi.hProcess, 5000);
TerminateProcess( pi.hProcess, 0 );
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
return FALSE;
}
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
return TRUE;
This function is returning BOOL;
Now I want if user has clicked CANCEL button, then It should not display any message.
if I am checking against this function's return value....that if it returns false, simple return; otherwise if true, display a message to the user. Even on clicking the cancel button it displays the message;
Regards,
Mbatra
|
|
|
|
|
Both the WM_TIMER message and the "button pressed" event are handled on the same thread in some order so you don't have any multithreading issues/race conditions, these message handlers never get executed in parallel but you don't know which of these gets executed first and it can easily happen that both of them get executed at the wrong time. These message handlers of yours are called in the following way: the gui thread has a message queue. The operating system periodically puts a WM_TIMER message into it. When the user presses the cancel button the OS puts in a message that will call your "button pressed" handler. It can easily happen that there is a button pressed handler and a WM_TIMER message in the queue and when your Cancel button pressed handler executes its already later to turn of the WM_TIMER messages - you will still receive one WM_TIMER message because it is already in the queue. It can happen in reverse order too, if the WM_TIMER arrives first it can easily happen that you already have a button pressed event in the queue so you will receive it even if you disable the cancel button.
Because both handler are executed on the same thread you can create cooperation between the two handlers very easily. Use a global variable or preferrable a class member variable in your window class, you can safely use/modify the same variables from both handlers. I would use a bool variable that indicates whether the process is still "running" or not, whether it is still actual to execute a message handler. In the very beginning of both handlers you return if this variable is false. If any of the handlers is called when this variable is true you immediately set it to false and you execute the handler. This way only one of the handlers gets executed at most once regardless of the number of WM_TIMER and button pressed events accumulated in the message queue of the gui.
Cosmetics: When executing any of the handlers, disable the cancel button. Especially in the cancel handler because there you are waiting for up to 5 seconds.
BTW, with WM_TIMER you could implement a cancel that doesn't "freeze" the gui. Define an enum that indicates the process launch state:
enum EProcessLaunchState
{
EProcessLaunchState_NotRunning,
EProcessLaunchState_Running,
EProcessLaunchState_Cancelled,
};
Use this instead of the bool. From your cancel button handler just set this enum variable to EProcessLaunchState_Cancelled, then grey out the cancel button and return immediately. In your WM_TIMER message handler you act depending on the value of this enum. If its EProcessLaunchState_NotRunning you do nothing. If its EProcessLaunchState_Running then you just check whether it is still alive. If its EProcessLaunchState_Cancelled then you Still check whether the process is alive just like in case of EProcessLaunchState_Running but if alive you additionally perform the following: increase a wait_time variable and if the wait_time exceeds the timout then you call TerminateProcess. If you know that you set up a WM_TIMER with 1 second period then you know that 5 WM_TIMER calls is your timeout. This way your gui doesnt freeze. With your solution you couldnt even grey out the cancel button when it gets presssed because in worst case you don't return control to your main loop so the message queue processing of the gui thread is suspended for 5 seconds preventing your gui from receiving any events including the redraw of your cancel button as grey.
modified 12-Aug-13 11:50am.
|
|
|
|
|
Your answer is wrong, your supposition is wrong, and you post is too long.
He specificaly asked about events, why not give him the answer instead of bleating on about postmessage?
|
|
|
|
|
There isn't such thing that "too long post" on codeproject, there are only insulting post like your posts. If it is too long for you then don't read it.
|
|
|
|
|
|
So you have an event that is shared across your process. Your UI creates a thread that waits on the event (unless you dont mind the UI being blocked in which case the main thread can wait on the event.
Your processing thread then sets that even when it is done.
Your UI (main thread or wait thread) then gets its wait satisfied and goes on to notify the user.
|
|
|
|
|
Your solution is unreliable because in case of a child process crash you wait for the event forever. If you wait for the process handle on the thread then its an alternative for the WM_TIMER polling with multithreading.
|
|
|
|
|
Why do you assume he is using a child process and you can of course timeout on an event or trigger the event for all sorts of reasons.
Of course we dont knoq the design of his code, if he is creating a work thread to do the transfer, but he asked about events, not about spawning processes, so your answer to him and to me is still wrong.
|
|
|
|
|
I assume a child process because he has written about it in the body of the messasge: "running a commandline operation". What is this if not a child process or in some extreme circumstances a process launched somewhere else? But you know what, let OP to decide that: he never told that it isn't a child process.
What happens if you timeout the event? You start waiting for it again? Or you assume that the process has terminated when it is still running? And how do you signal to the gui thread when the event becomes signaled without bleating on SendMessage/PostMessage/PostThreadMessage? I think we can safely ignore "bleating on" this because OP probably knows this all...
OP tries to solve a problem and he isn't using the right tools, that's it. Maybe the title of the question was only about events but have you read the body of the message? I provided some alternative solutions because as many other problems this one can also be solved in many ways - all of them having its pros/cons. The solution involves waiting/polling the process handle either from a thread or from a periodic event from 1 thread.
My advice to OP was using the poll solution because beginner's multithreading solutions are buggy in 99% of the cases and polling is a perfect alternative in this case, wait cancellation is also easier to implement with polling.
My advice to you: Learn how to respect people and how to talk to them accordingly. Giving wrong answers and making mistakes is okay, submitting positive criticism is OK, submitting destructive criticism and destroying morale on the forums is not okay, treating yourself and your solutions perfect in contrast to others and others' solution is not okay. As I previously mentioned respect is mutual or nonexistent. The fact that my post is "too" long according to you is unimportant. Whether my solution is good or not? Let OP and others decide...
And you know what? Why don't you submit your solutions if you think you are that smart?
|
|
|
|
|
Hi pasztorpisti,
Thanx for the answers. I am not creating any child processes. I only have to notify the UI that operation is completed.
I have implemented the same by handling WM_TIMER messages.
Regards,
Mbatra
|
|
|
|
|
Hi Erudite_Eric,
Thanx for the answers. I am not creating any child processes. I only have to notify the UI that operation is completed.
I have implemented the same by handling WM_TIMER messages.
Regards,
Mbatra
|
|
|
|
|
I think the CButton controls since painting this form
CButton controls the two on the left corner is rounded, two right angle square, or the two on the left corner is square, two right angle is round
This CButton control how to draw?
|
|
|
|
|
|
Have a concept drawing of the same?
|
|
|
|
|
Hi,
I am trying to change the tree view control's appearance using vc++. Initially it has + and - minus symbol when expanding and vice verse. Now i want to change the + and - symbol to arrow mark.
To bring the + and - minus symbol we can use the following default functionality
m_dwDefaultStyle |= TVS_HASBUTTONS |
TVS_HASLINES |
TVS_DISABLEDRAGDROP |
TVS_SHOWSELALWAYS;
Is it possible to change + and - symbol to arrow symbol using vc++?
Thanks,
Devika.
|
|
|
|
|
|
Hi
Thanks for your reply. But i was not talking about the folder change. The content which you was sent is about icon change. But i want to change the + and - symbol to arrow mark in the tree view control.
I couldn't attach the screenshot here. Its look like,
[+] Vehicle
[-] car
.
.
I want to change the arrow mark symbol instead that [+] and [-]
Please help me out on this
Thanks,
Devika
|
|
|
|
|
The only way you could do this would be either by using the owner draw feature, or by subclassing the control and adding your own code to handle the expand symbols.
Use the best guess
|
|
|
|
|
when u click a button the result should display in a particular edit box. but it is showing in two or three edit boxes.
|
|
|
|
|
Please do not expect people to guess what is happening. We cannot see your screen, and have no idea what your code is doing. Please edit your question and add some proper detail about your problem.
Use the best guess
|
|
|
|
|
This makes 0 cents. Please re-edit if you seriously want help.
"One man's wage rise is another man's price increase." - Harold Wilson
"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
"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous
|
|
|
|
|
Just stick a post it note over the ones you dont want to see it in.
|
|
|
|
|
hi
I want to the file name I write in edit box is valid or not.
I check these characters \/:*?\"<>|
but there is some other chars like Unicode,\t prn,com1,com2 etc
is there any api to check file is valid or not.
thanks.
|
|
|
|
|
You can use CreateFile with the GENERIC_WRITE and CREATE_NEW flags and check if it fails.
|
|
|
|
|
Whether you can create a file on a disk driver at a specified location may depend on more factors than a list of allowed unicode characters burnt into windows. One such factor can be the filesystem of the drive you are writing to. For this reason I think the previously mentioned CreateFile() test is probably one of the best and most reliable solutions.
|
|
|
|