|
Hello guys,
I have just moved into W32's serial communication, it is to be written to talk to a printer device via standard RS232. I have used basic functions such as CreateFile(), ReadFile() and WriteFile(). It all seems to be straight-forward when the communication will always be firstly WriteFile() to the device and then expect getting a response using ReadFile(). The tranmission from the device will always end with an EOT (0x04) so I'd use while loop on the ReadFile() until the EOT is received. By doing this, I somehow need a 'timeout' implementation within (say the loop breaks and gives an timeout error message after 3 seconds) otherwise it is possible the loop goes forever...Now the problem is I could not think of a way to go about inserting a timeout. Could it be done using SetTimer() etc?
BTW, I have placed the whole serial communication stuff in a separate worker thread so it does not interrupt the front GUI.
Can anyone help me with this?
Would be very much appreciated.
Thanks
|
|
|
|
|
You could, for example, create a global-level boolean variable, if you're not using classes. Then create a timer for the thread, and in the thread's message processing function, handle the WM_TIMER event. When the timer event is launched, the boolean is set to TRUE, which causes the while loop to exit.
Another option would be to use the Sleep function. This function will cause a thread to suspend until the time is elapsed, then continue the program execution from the next line of code. You could create a local variable, say an integer, which would go from 0 to 3, and during each while-loop iteration, the port is tested, then the thread sleeps for 1 second and increases the integer. The while-loop will automatically exit after 3 seconds.
The latter implementation only attempts to read the port at 1 second intervals, so it is not entirely reliable. If you need a more reliable system, decrease the sleep time and increase the iteration amount. An amount of going from 0...100 would already offer you the possibility to check the port at 30 ms intervals, if you aim for a 3 second time-out.
The advantage of the sleep function is the lack of the timer: there will be no extra message-processing needed. Know, however, that during the sleep time, the thread will not process any messages at all.
-Antti Keskinen
----------------------------------------------
The definition of impossible is strictly dependant
on what we think is possible.
|
|
|
|
|
Antti Keskinen wrote:
Another option would be to use the Sleep function.
Thnaks for the suggestions, Antti.
the sleep function came upon my head as well but I am not entirely sure if the function works in multi-threaded application? But from your answer, it looks like if the sleep is placed in the thread process call, it then will only suspend the thread process, not entire program, correct? In addition, I could not seem to locate sleep() or usleep() functions in my MFC apps? they give me undeclared identifier.
Finally, it is not really Visual C++ related. But how do I test my serial comm program is working using only the PC? Should I be able to see the sending string on HyperTerminal, if the program WriteFile() to the specified port (given it's done correctly)?
Thanks again
|
|
|
|
|
According to the MSDN reference:
The Sleep function suspends the execution of the current thread for at least the specified interval.
So, yes, it works in a multi-threaded application: it suspends the execution of the thread from which it is called. As for the reason of why you were unable to call the function from your programs: make sure you are calling the function Sleep() , not sleep() . The first one exists, the latter one doesn't. You must also include windows.h header file and link with Kernel32.lib library.
The serial ports are connectionless: they do not care to where they are connected, as long as a connection exists and the software using the communications configures the ports correctly. So, I believe the most easiest way is to utilize two serial ports. Most computers nowadays have two serial ports. Just obtain a cross-connected serial link cable (or do one yourself), then interconnect two of your computer's serial ports. Make your comms program write to the first port, and put some terminal program, e.x. HyperTerminal, to listen on the receiving end. Just remember to set the terminal program's port attributes correctly, otherwise you might get no results at all.
-Antti Keskinen
----------------------------------------------
The definition of impossible is strictly dependant
on what we think is possible.
|
|
|
|
|
Thank you again Antti,
they are the perfect answers. Really appreciated.
|
|
|
|
|
Use Mutex object.Although it is bit heavy interms of speed. But it is reliable and U will have control on it
|
|
|
|
|
Thanks SiddharthAtw,
I will have a look that as well.
|
|
|
|
|
How return the system menu ID when chlick and select "move" or "Size" or "Close" of the system menu?Please write some code for me, thanks!!
|
|
|
|
|
Look for WM_SYSCOMMAND , SC_MOVE , SC_SIZE , and SC_CLOSE .
A rich person is not the one who has the most, but the one that needs the least.
|
|
|
|
|
Thanks!But i think is how return the menu ID, that is when you click the "move" or "Size" or "Close".How doing i know click which command?Thanks!
|
|
|
|
|
Those are the menu identifiers. When you interact with the system menu, the window receives a WM_SYSCOMMAND message. Depending on the menu option selected, one of the SC_xxx types will be in the wParam parameter. Check out MSDN for plenty of examples.
A rich person is not the one who has the most, but the one that needs the least.
|
|
|
|
|
Thank you!
|
|
|
|
|
e.g.
int *pA = new int;
*pA = 10; //此时捕获事件?
SetAValue(10);
I don't want to overload the operator '='.
Can I do it?
or
What is the way the transaction of the database?
Best regards!
|
|
|
|
|
ummmmm
ur posting makes absolutely no sense whatsoever
please try to ask a meaningful question so all of chris's happy helpers (thats us btw) can answer you
"there is no spoon" biz stuff about me
|
|
|
|
|
Hi all, my app has a very time consuming function where all files on the computer are ennumerated, and ibe put a "cancel" button on the dialog so the user can cancel the ongoing operation, but (of course) the app doesnt process its messages while the ennumeration is running, so it never sees the user pressing the cancel button.
I know im supposed to implement some code inside the time consuming function so the app has a chance to get and process its messages, but i dont know exacly what functions to call. BTW, the app is a WTL - dialog based app (not MFC).
Any help would be much appreciated.
|
|
|
|
|
Ernesto D. wrote:
I know im supposed to implement some code inside the time consuming function so the app has a chance to get and process its messages, but i dont know exacly what functions to call.
You're supposed to do the work in a worker thread, which will leave your UI thread responsive.
Christian
I have drunk the cool-aid and found it wan and bitter. - Chris Maunder
|
|
|
|
|
or ... worst case scenario (if ur allergic to multi-threading) you should use PeakMessage() etc to see if anythings waiting
but thats bad and we dont do lazy bad things here do we?
"there is no spoon" biz stuff about me
|
|
|
|
|
Multithreading isn't something you just flip a switch and now your application is multithreaded. If you haven't laid the groundwork for resource locking, it would be a VERY bad idea to try to make an application multithreaded when a message pump is such a simple and functional alternative.
Tim Smith
I'm going to patent thought. I have yet to see any prior art.
|
|
|
|
|
Thanks for your answers, i was hoping to avoid multple treads, since the app is just a very "basic" utility that searches for certain files, but if its the only way to go then, so be it.
why would it be considered "bad" to use PeakMessage() etc.?
thanks.
|
|
|
|
|
Try this in your while loop..
<br />
if(GetMessage(&msg,NULL,0,0))<br />
{<br />
DispatchMessage(&msg);<br />
if(msg.wParam==WM_DESTROY)<br />
{<br />
PostQuitMessage(0);<br />
return;<br />
}<br />
}<br />
greatest thing is to do wot others think you cant suhredayan@omniquad.com
|
|
|
|
|
Hiya I want to call my child dialog(a dialog for searching..) when F2 is pressed. But I keep getting:
Debug Assertion Failed! File: wincore.cpp Line: 880
I call the dialog in PreTranslateMessage i.e
BOOL CCreateCustomerInvoice::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
if( pMsg->message == WM_KEYDOWN )
{
switch( pMsg->wParam )
{
case VK_F2: // if F2 key is pressed
CSearch search; // child dialog class
search.DoModal(); // call dialog
break;
} //end of switch
} //end of if
return CDialog::PreTranslateMessage(pMsg);
}
How do I do this?? Thanks.
|
|
|
|
|
ummmmm isnt ur child dialog being declared within the function and thereby it is a local variable that will disappear when the function exits?
make it class level and show it in the keypress handler
"there is no spoon" biz stuff about me
|
|
|
|
|
Well, i think u should handle it in the OnKeyDown handler.
afx_msg void OnKeyDown(
UINT nChar,
UINT nRepCnt,
UINT nFlags
); Then check the nChar value for VK_F2...
Weiye, Chen
When pursuing your dreams, don't forget to enjoy your life...
|
|
|
|
|
I know it sounds a little silly, but it's not. (or maybe it is ) I'm looking for a way to move awindow by dragging it not from the title bar (it doesn't have one), but by anywhere in the window.
I knew how this was done in Delphi, but with VisualC++, I'm still a litlle unconfortable.
Thanks a lot!
|
|
|
|
|
You have to catch WM_NCHITTEST and respond back HTCAPTION, not matter where you really are.
Look at the clock sample that came with MSVC (I think)
|
|
|
|