From: Me on
I got the transmit code working sending binary data for MSComm.

I have the following code for receiving a string of bytes.

bool CPSMDlg::GetChar()
{
COleVariant myVar;
int hr;
long lLen = 0;
BYTE *pAccess;
char buffer[255];

myVar.Attach (m_Comm.GetInput());

hr = SafeArrayGetUBound (myVar.parray, 1, &lLen); // Get the length
if (hr == S_OK)
{
lLen++; // upper bound is
zero based index
hr = SafeArrayAccess (myVar.parray,(void**)&pAccess); // lock array so
you can access it
if (hr == S_OK)
{
for (int i 0; i < lLen; i++) // Make a copy of
the data
buffer[i] = pAccess[i];
SafeArrayUnaccessData (myVar.parray); // unlock the
data
}
}
// COleVariant cleans itself up
}

How do I receive single bytes one at a time since the device may only send 1
byte in response to commands????

Thanks
eddie(a)eddie1.net


From: Joseph M. Newcomer on
I guess I've never before seen such convoluted code whose sole purpose is to receive a
single byte from a serial port. I tend to favor code that looks like

ReadFile(h, &buffer, 1, &bytesRead, NULL);

as being the most complicated code I want, and in addition, if I'm doing asynchronous I/O,
I'll create an event to indicate the completion, e.g.,

OVERLAPPED ovl;
BYTE buffer;
ovl.hEvent = event; // created a long time ago
if(!ReadFile(h, &buffer, 1, &bytesRead, NULL))
{ /* error */
DWORD err = ::GetLastError();
if(err != ERROR_IO_PENDING)
{ /* fatal error */
... deal with it
} /* fatal error */
HANDLE waiters[2];
waiters[0] = shutdownEvent;
waiters[1] = event;
DWORD wait = WaitForSingleObject(2, waiters, FALSE, INFINITE);
switch(wait)
{ /* wait */
case WAIT_OBJECT_0:
// shut down
break;
case WAIT_OBJECT_0+1:
break;
default:
ASSERT(FALSE);
... deal with error
} /* wait */
} /* error */
wnd->PostMessage(UWM_BYTE_RECEIVED, buffer, NULL);

I've used code like this in on the order of a dozen major applications, all of which are
out there running right now. Had I used MSCOMM, I probably wouldn't have a single running
app.

I note that nowhere in your code is there any error detection. Nor is there a way to
recover from a device that is hung waiting for a byte. Overall, there is an amazing amount
of convoluted work to interface to what is probably an inappropriate interface in the
first place. If you simply take as a premise that MSCOMM is the wrong approach, the
problem becomes trivial by comparison. And it has issues such as reliability and
robustness that appear to be absent in the MSCOMM solution.

I suppose I might be able to offer more advice if MSCOMM were documented, but I am unable
to locate any documentation in the MSDN. Probably one of the reasons I don't use it; I
don't use undocumented interfaces. If it were an important control, there would be
documentation on it. That is, I could type "MSCOMM" to the index, or possibly to the
search window of the MSDN, and get an actual, real, live, document that describes how to
use the control. (The best I found was a pointer to a nonexistent file, comm98.chm, which
does not exist on my machine, and I have the full Visual Studio 6 and Visual Studio 7
installations, the latest platform SDK, and the second-latest MSDN library installed, so
the lack of documentation clearly means this is an inappropriate control). In the absence
the the ability to find documentation, the presumption is that this control is distributed
as a joke control, whose purpose is not to solve problems but to create them. Why elect to
use something that is undocumented, hard to use, and probably completely inappropriate,
and then try to force a solution out of it?
joe


On Wed, 16 Feb 2005 04:01:39 GMT, "Me" <me(a)right.her> wrote:

>I got the transmit code working sending binary data for MSComm.
>
>I have the following code for receiving a string of bytes.
>
>bool CPSMDlg::GetChar()
>{
> COleVariant myVar;
> int hr;
> long lLen = 0;
> BYTE *pAccess;
> char buffer[255];
>
> myVar.Attach (m_Comm.GetInput());
>
> hr = SafeArrayGetUBound (myVar.parray, 1, &lLen); // Get the length
> if (hr == S_OK)
> {
> lLen++; // upper bound is
>zero based index
> hr = SafeArrayAccess (myVar.parray,(void**)&pAccess); // lock array so
>you can access it
> if (hr == S_OK)
> {
> for (int i 0; i < lLen; i++) // Make a copy of
>the data
> buffer[i] = pAccess[i];
> SafeArrayUnaccessData (myVar.parray); // unlock the
>data
> }
> }
> // COleVariant cleans itself up
>}
>
>How do I receive single bytes one at a time since the device may only send 1
>byte in response to commands????
>
>Thanks
>eddie(a)eddie1.net
>

Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Ed on
Hi,

I still cannot get the receive working.
This is the last thing I have tried and all I get is garbage back.
All I seem to get is 0x01 even when I am supposed to get text.
Please take a look and feel free to suggest. I really need binary to work.

void CPSMDlg::OnOnCommMscomm1()
{
Char ed[2048];
FILE *in;
COleVariant Value;

if (m_comm.GetCommEvent() == 2)
{
Value = m_comm.GetInput();
CString Buffer = V_BSTR(&Value);
ed[current]=Buffer[0];
ed[current+1]=0x00;
in = fopen("c:\\psm\\a1.dat", "wb");
fwrite(ed, current, 1, in);
fclose(in);
current++;
AfxMessageBox(Buffer);
}
}

current is a count thats reset before I request any data.

Thanks in advance,
Ed
-----------------------------------------------------------------------------



"Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message
news:2h671151c6kbs7l3jikhkd9n35jtrs749b(a)4ax.com...
>I guess I've never before seen such convoluted code whose sole purpose is
>to receive a
> single byte from a serial port. I tend to favor code that looks like
>
> ReadFile(h, &buffer, 1, &bytesRead, NULL);
>
> as being the most complicated code I want, and in addition, if I'm doing
> asynchronous I/O,
> I'll create an event to indicate the completion, e.g.,
>
> OVERLAPPED ovl;
> BYTE buffer;
> ovl.hEvent = event; // created a long time ago
> if(!ReadFile(h, &buffer, 1, &bytesRead, NULL))
> { /* error */
> DWORD err = ::GetLastError();
> if(err != ERROR_IO_PENDING)
> { /* fatal error */
> ... deal with it
> } /* fatal error */
> HANDLE waiters[2];
> waiters[0] = shutdownEvent;
> waiters[1] = event;
> DWORD wait = WaitForSingleObject(2, waiters, FALSE, INFINITE);
> switch(wait)
> { /* wait */
> case WAIT_OBJECT_0:
> // shut down
> break;
> case WAIT_OBJECT_0+1:
> break;
> default:
> ASSERT(FALSE);
> ... deal with error
> } /* wait */
> } /* error */
> wnd->PostMessage(UWM_BYTE_RECEIVED, buffer, NULL);
>
> I've used code like this in on the order of a dozen major applications,
> all of which are
> out there running right now. Had I used MSCOMM, I probably wouldn't have a
> single running
> app.
>
> I note that nowhere in your code is there any error detection. Nor is
> there a way to
> recover from a device that is hung waiting for a byte. Overall, there is
> an amazing amount
> of convoluted work to interface to what is probably an inappropriate
> interface in the
> first place. If you simply take as a premise that MSCOMM is the wrong
> approach, the
> problem becomes trivial by comparison. And it has issues such as
> reliability and
> robustness that appear to be absent in the MSCOMM solution.
>
> I suppose I might be able to offer more advice if MSCOMM were documented,
> but I am unable
> to locate any documentation in the MSDN. Probably one of the reasons I
> don't use it; I
> don't use undocumented interfaces. If it were an important control, there
> would be
> documentation on it. That is, I could type "MSCOMM" to the index, or
> possibly to the
> search window of the MSDN, and get an actual, real, live, document that
> describes how to
> use the control. (The best I found was a pointer to a nonexistent file,
> comm98.chm, which
> does not exist on my machine, and I have the full Visual Studio 6 and
> Visual Studio 7
> installations, the latest platform SDK, and the second-latest MSDN library
> installed, so
> the lack of documentation clearly means this is an inappropriate control).
> In the absence
> the the ability to find documentation, the presumption is that this
> control is distributed
> as a joke control, whose purpose is not to solve problems but to create
> them. Why elect to
> use something that is undocumented, hard to use, and probably completely
> inappropriate,
> and then try to force a solution out of it?
> joe
>
>
> On Wed, 16 Feb 2005 04:01:39 GMT, "Me" <me(a)right.her> wrote:
>
>>I got the transmit code working sending binary data for MSComm.
>>
>>I have the following code for receiving a string of bytes.
>>
>>bool CPSMDlg::GetChar()
>>{
>> COleVariant myVar;
>> int hr;
>> long lLen = 0;
>> BYTE *pAccess;
>> char buffer[255];
>>
>> myVar.Attach (m_Comm.GetInput());
>>
>> hr = SafeArrayGetUBound (myVar.parray, 1, &lLen); // Get the
>> length
>> if (hr == S_OK)
>> {
>> lLen++; // upper bound
>> is
>>zero based index
>> hr = SafeArrayAccess (myVar.parray,(void**)&pAccess); // lock array
>> so
>>you can access it
>> if (hr == S_OK)
>> {
>> for (int i 0; i < lLen; i++) // Make a copy
>> of
>>the data
>> buffer[i] = pAccess[i];
>> SafeArrayUnaccessData (myVar.parray); // unlock the
>>data
>> }
>> }
>> // COleVariant cleans itself up
>>}
>>
>>How do I receive single bytes one at a time since the device may only send
>>1
>>byte in response to commands????
>>
>>Thanks
>>eddie(a)eddie1.net
>>
>
> Joseph M. Newcomer [MVP]
> email: newcomer(a)flounder.com
> Web: http://www.flounder.com
> MVP Tips: http://www.flounder.com/mvp_tips.htm


 | 
Pages: 1
Prev: listView question
Next: Can't Show Client Edge