Click here to Skip to main content
12,076,206 members (32,973 online)
Rate this:
Please Sign up or sign in to vote.
Hello everyone!

I have a question like this: let say I have a window form application written in Visual C++ 2010. There are 4 buttons (button1, button2, button3, button4) on the main form. Each button of button1, button2, button3 is associated with an event (event1, event2, event3 respectively). Now what I want to do is when I click on button4, event1 begins to start, after for example 5 seconds, the event2 begins to start and after 4 seconds the event3 begins to start. How could I do that? I think we could use something like Thread->Sleep(int miliseconds) or Timer.

This is what I've added after some people said that my purpose is weird.
Well acctually I'm using visual C++ 2010 to control a washing machine through a Analog-to-digital converter. Each button is for controlling an element like an engine (or motor ), or something like a valve or water pumps. So Each element is turned on after some time and so on. The button4 is for a particular algorithm of controlling the process of water flowing.

Any help would be appreciated!
Thanks in advanced!
Posted 12-Jun-12 21:17pm
Edited 13-Jun-12 3:39am
SAKryukov 13-Jun-12 2:37am
Is it .NET? And C++/CLI (not C++)? Then tag it properly. You platform? Tag it. You won't be able to get valid answers if you do not provide comprehensive relevant information.
SAKryukov 13-Jun-12 2:39am
Also, why such a weird schema of events? What are event types you are interested in? Don't think you can get valid answers if you are not motivating weird things. Here is why: if one suspects that what you want is wrong, who will waste time on explaining how, as you won't be able to use help anyway. That's why you should start from explaining your goal.
svatstika 13-Jun-12 8:35am
Thank SAKrykov for such a good advice. I just did not have time to think and explain clearly. So I've just edited my question and hope that the question now is clear.
Mohibur Rashid 13-Jun-12 3:00am
If you tell your purpose of this weird thing? if it is the requirements of your project then re-design the project.
Rate this: bad
Please Sign up or sign in to vote.

Solution 2

Okay, after reading your updated question - forget what I wrote below, although some of the principles may come in handy...

It sounds a bit of a weird way to control a washing machine - having the user press buttons to trigger things manually. It's like using an old twin tub from the 70s. Pump water in, drop in soap powder, set the machine stirring. When it's finished try and get the clothes from the washer to the spinner without flooding the kitchen and so on.

Wouldn't it be better to model your washing machine's low level controls as a set of objects then link them together using various programs, the way an automatic washing machine does today [1]? For analogue control you might as well implement a hardware timer as well rather than relying on the computer - so instead of the computer saying "Okay, start...1, 2, 3, 4, 5... stop!" to the various devices it can just say: "Do your stuff for 5 seconds." This avoids the embarrassment of the computer crashing and the motor burning out as it wasn't meant to be on full spin for half an hour.

Anyway, sounds like the question could be more "here's a design for a control system, what's wrong with it?" more than one about windows programming.

[1] Oo, hang on, you are trying that. One cycle component per button, fired from the first one clicked rather than a triggered dial. The problems with doing it this way are:

- User clicks the start cycle button then for a laugh clicks the spin. The pumps going like crazy trying to force water in while the drum is rotating like mad.
- The computer's doing the timing. Windows is event driven and while on modern hardware I haven't seen this happen in 10 years it can delay timer messages. You'll have to use multimedia timers or some higher resolution ones.

Good luck!


PS: First reply...

Provided this is Win32 we're talking about and not some new fangled .Net malarkey and you mean form application in it's traditional sense then the way I'd go for this would be (using MFC and raw Win32)

1. Sort out where you're going to add code...

MFC: Derive a new class from CButton
Win32: Implement a window procedure that just forwards calls another window procedure

2. Sort out where you're going to store the object you want to forward messages to...

MFC: Implement a constructor that takes and saves a CWnd * as a parameter. This is the address of the CWnd object that you want to trigger a simulated button press on.
Win32: Write a function to add a property to a window called something like L"relay_to" which takes the HWND to the window you want to trigger a simulated button press on (using SetProp).

3. Sort out how you're going to handle the button click...

MFC: Override OnLButtonUp. The override sets a timer (using CWnd::SetTimer on itself) and add the function to the derived class's message map.
Win32: In your window procedure add a handler for WM_LBUTTONUP. In it call SetTimer.

4. Sort out how you're going to send a WM_LBUTTONUP to another button...

MFC: Override OnTimer. The override kills the timer (CWnd::KillTimer) and sends a WM_LBUTTONUP message to the window supplied to the constructor (CWnd::SendMessage). Add the function to the derived class's message map.
Win32: In your window procedure add a handler for WM_TIMER. In it do a KillTimer on the the window and send a WM_LBUTTONUP message to the HWND stored as a property (using SendMessage and GetProp).

5. Wire the whole unholy mess together starting with the buttons...

MFC: In your dialogue box's constructor make sure that button 1 has a pointer to button 2 which has a pointer to button 3 ad nauseum.
Win32: In WM_INITDIALOG of your dialogue box use the function you wrote in 2 to attach the window handle of button 2 to button 1 and so on.

6. ... then subclass the windows...

MFC: Use DDX_Control in your dialogues UpdateData to route windows messages through the MFC message map for your buttons. One call per button.
Win32: Use SubclassWindow to set the window procedure for the buttons to be the one you wrote earlier

7. Stand back, pull the chain and hope it all works.

There's going to be some bits I missed out of that lot (like where do you put the window procedure pointer you get when you subclass in win32) but it should give you an idea of what you're trying to do. And what a balls ache it is.

Interestingly the solution to this is about as complicated using MFC as it is using raw win32 - which just goes to show that MFC is possibly not as high level as most people would like it to be!

The other interesting bits here are all the ways you can simplify this lot and make it vaguely reusable (introduce an action interface in MFC and Win32 so you can dynamically change window's behaviour, add a jump table in Win32 to save needing big switch statements) but that's a whole 'nother topic.

Still want to do it? Smile | :) If you do you'll come out of it knowing more about windows messaging than man was meant to know.
Aescleal 13-Jun-12 22:48pm
Hi Mr. Univoter, any chance you can tell me why you voted me down? This is so I can either/or:

- improve my answer and perhaps learn how to express myself better next time
- learn something
- disagree with you and say why and let other people make up their mind

I don't do tit for tat univoting so don't let that stand in your way!

Rate this: bad
Please Sign up or sign in to vote.

Solution 3

Lets say your first button is the inlet water valve, the second starts the engine, the third opens the outlet valve, and the fourth runs a particular seqence.

Your code should contain control functions such as:

ControlInletValve(BOOL on_or_off);
ControlOutletValve(BOOL on_or_off);
ControlEngine((BOOL on_or_off);

In your button event handlers and timer handler, you will have the basic skeleton code like this (you understand this is not compilable code but rather the correct code structure for your problem):

static int phase;
void CBlaBla::OnButtonClickedButton1()
	ControlInletValve(TRUE); // or you could make it a toggle
void CBlaBla::OnButtonClickedButton2()
	ControlEngine(TRUE); // or you could make it a toggle
void CBlaBla::OnButtonClickedButton3()
	ControlOutletValve(TRUE); // or you could make it a toggle
void CBlaBla::OnButtonClickedButton4()
	phase = 0; // this will activate your sequence under timer control
void CBlaBla::InitTimer()
       phase = LAST_PHASE;
       // start self-restarting timer has no effect until "phase" is set to a 
       // value not equal to LAST_PHASE

void CBlaBla::OnTimer()
	switch (phase)
		case 0:
		case 1:
		// and so on depending on your washing machine algorithm

		case LAST_PHASE:
			// sequence not active, nothing to do
	// call OnTimer of the base class here somewhere
Rate this: bad
Please Sign up or sign in to vote.

Solution 1

You just can call in the function the event handlers for the next button
for example from OnButtonClickButton1 you can call OnButtonClickButton2 and so on and you can put one timer inside each function so it will be called after the desired time
SAKryukov 13-Jun-12 2:42am
What is "call OnButtonClickButton2"? You cannot "call" a button. What timer? How do you know what is the type of the event and the purpose of it? Do you know that you cannot fire an event from anywhere except the instance of a type where it is declared?

Giving answers on something you do not understand yourself, not even close, is not nice. Therefore, I just had to vote 1, sorry.
Argonia 13-Jun-12 3:10am
You didnt understand what i wrote call from a function you call the handler for the next button . OnButtonClickButoon1 is a handler function its not a button
stib_markc 13-Jun-12 4:22am
What you did is meaningless, although it works. Event handlers are there for a purpose, they are called by your application, when the specific event occurs. So, calling one event handler in another event handler? Weird!!
Aescleal 13-Jun-12 8:47am
I've seen it happen in two places in MFC apps:

- to avoid calling CWnd::SendMessage
- derived class handlers calling base class handlers

Conceptually the first one may seem a bit bent but it's the same as sending a window a message - without the whole sending a window a message thing. The second one is essentially the same as subclassing a Win32 window, again without doing the window subclassing thing.
stib_markc 14-Jun-12 0:52am
Yes, I know about the first case, but still, I generally use PostMessage or PostThreadMessage for sending messages, which is very comfortable.
Aescleal 14-Jun-12 1:18am
So do I, but a fair amount of example code uses direct calls and it's easy to pick up the habit.
Aescleal 13-Jun-12 8:51am
I can see what he meant - he was assuming Win32 using something like MFC. Trouble is he left out a load of the details - i.e. either having to handle WM_COMMAND in the dialogue, reflecting messages back into the controls OR subclassing a raw control. None of which are trivial the first time you try it.
stib_markc 14-Jun-12 0:45am
Yes, I cannot think of any other thing.
Argonia 14-Jun-12 1:46am
actually its she :) Yes i assumed that he is using MFC
Aescleal 14-Jun-12 3:26am
Sorry, I'm guilty of assuming all software engineers are men, apart from my wife that is so I've got less excuse than most!
michaelmel 13-Jun-12 20:54pm
OnButtonClickXXX are just regular functions called through event handling mechanism. What you see in the function body is what you get. There is absolutely nothing wrong or weird with calling OnButtonClickXXX from another function, including a timer handler e.g. OnTimer. Full marks to Argonia from me

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month

Advertise | Privacy | Mobile
Web03 | 2.8.160208.1 | Last Updated 13 Jun 2012
Copyright © CodeProject, 1999-2016
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100