Discussion:
BYTE to LPCTSTR ?
(too old to reply)
Robby
2006-06-24 04:51:01 UTC
Permalink
Hi,

I have the following line of code which reads bytes from an rs232 port:
Please consider the following code:

============================================
DWORD dwBytesRead = 0;
BYTE abBuffer[100];
TCHAR szBuffer[100];

MySerial.Read(abBuffer,sizeof(abBuffer),&dwBytesRead);
============================================

Now, I need to print abBuffer to the screen, god knows I tried !

TextOut(hdc,100,100,abBuffer,100); //no good!
TextOut(hdc,100,100,TEXT(abBuffer),100); // no good!
TextOut(hdc,100,100,(char)abBuffer,100); //I didn't expect this one
to work!
TextOut(hdc,100,100,wsprintf(szBuffer,TEXT("%s")),abBuffer); //Forget it!
:(

By now I have looked for answers in Petzold, Osborn and SAM's books and I
now need help! >>>> a g a i n!

Anyone!

BYTE is typedefed in Windows as so,

typedef unsigned char BYTE;

-so this tells me that a byte is really defined as a char... right ?
-A char is 8 bits ... right ?

So if the 4th parameter of TextOut takes a LPCTSTR, then how would I convert
this so that TextOut would accept it ?

Ooooohhhhfffff !

Anyone.....Please!
--
Best regards
Roberto
John Carson
2006-06-24 06:35:09 UTC
Permalink
Post by Robby
Hi,
I have the following line of code which reads bytes from an rs232
============================================
DWORD dwBytesRead = 0;
BYTE abBuffer[100];
TCHAR szBuffer[100];
MySerial.Read(abBuffer,sizeof(abBuffer),&dwBytesRead);
============================================
Now, I need to print abBuffer to the screen, god knows I tried !
TextOut(hdc,100,100,abBuffer,100); //no good!
TextOut(hdc,100,100,TEXT(abBuffer),100); // no good!
TextOut(hdc,100,100,(char)abBuffer,100); //I didn't expect
this one to work!
TextOut(hdc,100,100,wsprintf(szBuffer,TEXT("%s")),abBuffer);
//Forget it! :(
"no good" is not useful information. Telling us the actual error would be
useful information. Does it not compile (if not, what error message do you
get?), or output junk or..? I will assume that it doesn't compile.
Post by Robby
By now I have looked for answers in Petzold, Osborn and SAM's books
and I now need help! >>>> a g a i n!
Anyone!
BYTE is typedefed in Windows as so,
typedef unsigned char BYTE;
-so this tells me that a byte is really defined as a char... right ?
-A char is 8 bits ... right ?
So if the 4th parameter of TextOut takes a LPCTSTR, then how would I
convert this so that TextOut would accept it ?
Text processing functions in Windows come in two versions: an "A" for "Ansi"
version and a "W" for "wide character" version. Ignoring some complications,
the A version is for 8 bit chars and the W version is for 16 bit Unicode
wchar_t s. Thus there are both TextOutA and TextOutW.

TextOut is a macro, defined as

#ifdef UNICODE
#define TextOut TextOutW
#else
#define TextOut TextOutA
#endif

Thus, depending on whether or not UNICODE is #defined, TextOut is either
TextOutW or TextOutA.

Similarly, depending on whether or not UNICODE is #defined, LPCTSTR is a
typedef that is either LPCWSTR (for 16 bit wchar_t s) or LPCSTR (for 8 bit
chars).

I am guessing that your problem is that UNICODE is #defined, so you are
getting TextOutW which takes a string of wchar_t s, whereas you are feeding
it a string of chars.

If so, you have two possibilities:

(i) don't define UNICODE, or
(ii) call TextOutA rather than TextOut, i.e., manually select the version of
TextOut for 8 bit chars.

There is a third possibility --- call MultiByteToWideChar to convert your 8
bit chars to 16 bit wchar_t s --- but that seems like overkill unless you
are going to be processing the string in more ways than just outputting it.
--
John Carson
Robby
2006-06-24 17:43:02 UTC
Permalink
Hello Heinz and John!

and its a success!

Bytes can be read and printed on the screen or stored in an array!

I did try TextOutA, however when I typed the "(", intellisense didn't come
on! So I tried to look up the parameters in help, but I was unsuccessfull.
Probably, the parameters are the same as TextOut function but I just didn't
want to continue on a function I wasn't too sure about.... maybe later I will
look into it!

So I adopted the MultiByteToWideChar function, and it worked! At first there
was a glitch with the 3rd parameter, however, I type casted it to reflect a
LPCSTR as so:

MultiByteToWideChar(CP_ACP,0, (LPCSTR) abBuffer,30,szBuffer,30);

Although, as I read the description of the parameters, I didn't really
understand what they mean by the following explaination for the dwFlags
parameter though:

"[in] Indicates whether to translate to precomposed or composite-wide
characters (if a composite form exists), whether to use glyph characters in
place of control characters, and how to deal with invalid characters. You can
specify a combination of the following flag constants. "

[and]

"A composite character consists of a base character and a nonspacing
character, each having different character values. A precomposed character
has a single character value for a base/nonspacing character combination. In
the character è, the e is the base character and the accent grave mark is the
nonspacing character.

The function's default behavior is to translate to the precomposed form. If
a precomposed form does not exist, the function attempts to translate to a
composite form.

The flags MB_PRECOMPOSED and MB_COMPOSITE are mutually exclusive. The
MB_USEGLYPHCHARS flag and the MB_ERR_INVALID_CHARS can be set regardless of
the state of the other flags. "


I read it three (3) times... I guess I would need some definitions
dictionary concerning terms like, Precomposite, glyph and non-spacing
character!

I never ran into this before.... Please do not feel obligated to explain
this, I think you have done enough good for me.... Thanks for your help guys!
--
Appreciated regards
Roberto
Post by John Carson
Post by Robby
Hi,
I have the following line of code which reads bytes from an rs232
============================================
DWORD dwBytesRead = 0;
BYTE abBuffer[100];
TCHAR szBuffer[100];
MySerial.Read(abBuffer,sizeof(abBuffer),&dwBytesRead);
============================================
Now, I need to print abBuffer to the screen, god knows I tried !
TextOut(hdc,100,100,abBuffer,100); //no good!
TextOut(hdc,100,100,TEXT(abBuffer),100); // no good!
TextOut(hdc,100,100,(char)abBuffer,100); //I didn't expect
this one to work!
TextOut(hdc,100,100,wsprintf(szBuffer,TEXT("%s")),abBuffer);
//Forget it! :(
"no good" is not useful information. Telling us the actual error would be
useful information. Does it not compile (if not, what error message do you
get?), or output junk or..? I will assume that it doesn't compile.
Post by Robby
By now I have looked for answers in Petzold, Osborn and SAM's books
and I now need help! >>>> a g a i n!
Anyone!
BYTE is typedefed in Windows as so,
typedef unsigned char BYTE;
-so this tells me that a byte is really defined as a char... right ?
-A char is 8 bits ... right ?
So if the 4th parameter of TextOut takes a LPCTSTR, then how would I
convert this so that TextOut would accept it ?
Text processing functions in Windows come in two versions: an "A" for "Ansi"
version and a "W" for "wide character" version. Ignoring some complications,
the A version is for 8 bit chars and the W version is for 16 bit Unicode
wchar_t s. Thus there are both TextOutA and TextOutW.
TextOut is a macro, defined as
#ifdef UNICODE
#define TextOut TextOutW
#else
#define TextOut TextOutA
#endif
Thus, depending on whether or not UNICODE is #defined, TextOut is either
TextOutW or TextOutA.
Similarly, depending on whether or not UNICODE is #defined, LPCTSTR is a
typedef that is either LPCWSTR (for 16 bit wchar_t s) or LPCSTR (for 8 bit
chars).
I am guessing that your problem is that UNICODE is #defined, so you are
getting TextOutW which takes a string of wchar_t s, whereas you are feeding
it a string of chars.
(i) don't define UNICODE, or
(ii) call TextOutA rather than TextOut, i.e., manually select the version of
TextOut for 8 bit chars.
There is a third possibility --- call MultiByteToWideChar to convert your 8
bit chars to 16 bit wchar_t s --- but that seems like overkill unless you
are going to be processing the string in more ways than just outputting it.
--
John Carson
John Carson
2006-06-25 00:53:04 UTC
Permalink
Post by Robby
Hello Heinz and John!
and its a success!
Bytes can be read and printed on the screen or stored in an array!
I did try TextOutA, however when I typed the "(", intellisense didn't
come on! So I tried to look up the parameters in help, but I was
unsuccessfull. Probably, the parameters are the same as TextOut
function but I just didn't want to continue on a function I wasn't
too sure about.... maybe later I will look into it!
You won't find TextOutA in the help, nor will you find the A or W versions
of any of the other functions or structures. They are identical to the
function minus the A or W except that the A always takes narrow character
strings and the W always takes wide character strings.
Post by Robby
So I adopted the MultiByteToWideChar function, and it worked! At
first there was a glitch with the 3rd parameter, however, I type
MultiByteToWideChar(CP_ACP,0, (LPCSTR) abBuffer,30,szBuffer,30);
Yes, as Heinz pointed out, BYTE is unsigned char and functions that take a
pointer to char require a cast before they will accept a pointer to unsigned
char. This is a bit surprising really because a function that takes a char
will accept an unsigned char as an argument without requiring a cast. It is
only when pointers are involved that you need the cast.

The same thing is true with ints. A function that takes an int will accept
an unsigned int, but a function that takes a pointer to int will only accept
a pointer to unsigned int with a cast.

The above refers to C++. The cast is not necessary in C.
Post by Robby
Although, as I read the description of the parameters, I didn't really
understand what they mean by the following explaination for the
"[in] Indicates whether to translate to precomposed or composite-wide
characters (if a composite form exists), whether to use glyph
characters in place of control characters, and how to deal with
invalid characters. You can specify a combination of the following
flag constants. "
[and]
"A composite character consists of a base character and a nonspacing
character, each having different character values. A precomposed
character has a single character value for a base/nonspacing
character combination. In the character è, the e is the base
character and the accent grave mark is the nonspacing character.
The function's default behavior is to translate to the precomposed
form. If a precomposed form does not exist, the function attempts to
translate to a composite form.
The flags MB_PRECOMPOSED and MB_COMPOSITE are mutually exclusive. The
MB_USEGLYPHCHARS flag and the MB_ERR_INVALID_CHARS can be set
regardless of the state of the other flags. "
I read it three (3) times... I guess I would need some definitions
dictionary concerning terms like, Precomposite, glyph and non-spacing
character!
I always just pass 0 for that argument.

A glyph is just the visual representation of a character --- what you see,
as opposed to its Unicode number or whatever.

I presume that a non-spacing character is just any character that is not a
space or a tab or a newline character or a carriage return.

As for precomposed characters, with many characters there is a choice in how
to produce them. Suppose we have the letter e with an accent over the top.
This can be produced in two ways:

1. From the letter e and the accent character.
2. From a single character that comes with the accent already present.

In case 1, you have two characters with two different character codes. In
case 2, you have a single character with a single character code. The
character in case 1 is a "composite" character, while the character in case
2 is a "precomposed" character.

The flags control the circumstances in which composite characters are
converted to precomposed characters.
--
John Carson
Robby
2006-06-26 22:38:01 UTC
Permalink
Thankyou guys I really appreciate yor feedback....

I was meaning to ask, can you guys give a quick look at my 'rs232-help!'
post, I really am having a hard time with it, and I must say that I am
discouraged trying to solve the same problem for 4 days now.

I don't know what to do anymore!

Fellow news groups have been very helpfull and I thank them alot. Until last
week I never used rs232, and this is my first attempt ever with rs232, and I
feel like I am missing some small detail, but I don't know what.

Thnankyou for your generosity!
--
Best regards
Robert
Post by John Carson
Post by Robby
Hello Heinz and John!
and its a success!
Bytes can be read and printed on the screen or stored in an array!
I did try TextOutA, however when I typed the "(", intellisense didn't
come on! So I tried to look up the parameters in help, but I was
unsuccessfull. Probably, the parameters are the same as TextOut
function but I just didn't want to continue on a function I wasn't
too sure about.... maybe later I will look into it!
You won't find TextOutA in the help, nor will you find the A or W versions
of any of the other functions or structures. They are identical to the
function minus the A or W except that the A always takes narrow character
strings and the W always takes wide character strings.
Post by Robby
So I adopted the MultiByteToWideChar function, and it worked! At
first there was a glitch with the 3rd parameter, however, I type
MultiByteToWideChar(CP_ACP,0, (LPCSTR) abBuffer,30,szBuffer,30);
Yes, as Heinz pointed out, BYTE is unsigned char and functions that take a
pointer to char require a cast before they will accept a pointer to unsigned
char. This is a bit surprising really because a function that takes a char
will accept an unsigned char as an argument without requiring a cast. It is
only when pointers are involved that you need the cast.
The same thing is true with ints. A function that takes an int will accept
an unsigned int, but a function that takes a pointer to int will only accept
a pointer to unsigned int with a cast.
The above refers to C++. The cast is not necessary in C.
Post by Robby
Although, as I read the description of the parameters, I didn't really
understand what they mean by the following explaination for the
"[in] Indicates whether to translate to precomposed or composite-wide
characters (if a composite form exists), whether to use glyph
characters in place of control characters, and how to deal with
invalid characters. You can specify a combination of the following
flag constants. "
[and]
"A composite character consists of a base character and a nonspacing
character, each having different character values. A precomposed
character has a single character value for a base/nonspacing
character combination. In the character è, the e is the base
character and the accent grave mark is the nonspacing character.
The function's default behavior is to translate to the precomposed
form. If a precomposed form does not exist, the function attempts to
translate to a composite form.
The flags MB_PRECOMPOSED and MB_COMPOSITE are mutually exclusive. The
MB_USEGLYPHCHARS flag and the MB_ERR_INVALID_CHARS can be set
regardless of the state of the other flags. "
I read it three (3) times... I guess I would need some definitions
dictionary concerning terms like, Precomposite, glyph and non-spacing
character!
I always just pass 0 for that argument.
A glyph is just the visual representation of a character --- what you see,
as opposed to its Unicode number or whatever.
I presume that a non-spacing character is just any character that is not a
space or a tab or a newline character or a carriage return.
As for precomposed characters, with many characters there is a choice in how
to produce them. Suppose we have the letter e with an accent over the top.
1. From the letter e and the accent character.
2. From a single character that comes with the accent already present.
In case 1, you have two characters with two different character codes. In
case 2, you have a single character with a single character code. The
character in case 1 is a "composite" character, while the character in case
2 is a "precomposed" character.
The flags control the circumstances in which composite characters are
converted to precomposed characters.
--
John Carson
Heinz Ozwirk
2006-06-25 07:31:12 UTC
Permalink
Post by Robby
Hello Heinz and John!
and its a success!
Bytes can be read and printed on the screen or stored in an array!
I did try TextOutA, however when I typed the "(", intellisense didn't come
on! So I tried to look up the parameters in help, but I was unsuccessfull.
Probably, the parameters are the same as TextOut function but I just didn't
want to continue on a function I wasn't too sure about.... maybe later I will
look into it!
Most functions in the Windows API are described in terms of TCHAR, LPTSTR,
LPCTSTR etc, but actually for these functions, there are realyy two
functions, one which accepts char, LPSTR, LPCSTR etc and one which accepts
wchar_t, LPWSTR, LPCWSTR etc. When a function is described as

int TextOut(HDC, int, int, LPCTSTR, int)

there are actually two functions

int TextOutA(HDC, int, int, LPCSTR, int)
int TextOutW(HDC, int, int, LPCWSTR, int)

and a #define for TextOut

#if defined(UNICODE)
#define TextOut TextOutW
#else
#define TextOut TextOutA
#endif

InterlliSense (which is not really intelligent and doesn't always make
sense) only knows about the generic functions (TextOut), but when you look
up the definition of TextOut (place the caret on TextOut and hit F12) it
will send you to the actual define.

The idea behind all those defines has been that it should be easy to switch
from multi byte to unicode by only changing one setting on the program's
property page and rebuild the project. Also, that's the reason why you
should use _T("some string") instead of "some string" or L"some string".
Post by Robby
So I adopted the MultiByteToWideChar function, and it worked! At first there
was a glitch with the 3rd parameter, however, I type casted it to reflect a
MultiByteToWideChar(CP_ACP,0, (LPCSTR) abBuffer,30,szBuffer,30);
Although, as I read the description of the parameters, I didn't really
understand what they mean by the following explaination for the dwFlags
0 is quite usefull in almost all cases. Also for WideCharToMultiByte the
dwFlags, lpDefaultChar and lpUsedDefaultChar arguments can almost allways be
0.
Post by Robby
"[in] Indicates whether to translate to precomposed or composite-wide
characters (if a composite form exists), whether to use glyph characters in
place of control characters, and how to deal with invalid characters. You can
specify a combination of the following flag constants. "
...
Post by Robby
I read it three (3) times... I guess I would need some definitions
dictionary concerning terms like, Precomposite, glyph and non-spacing
character!
As John already explained, there are two ways to put one of those fancy
decorations that non-american languages sometimes use above or below another
character. You can them as two symbols -- the accent folowed by the plain
character -- then it would be a composite character becose it is composed of
two (or more) symbols (or glyphs), or, for some of these composite
characters, there may be a single symbol, which exists in the characterset.

Since the accents put above or below a character to not add space to the
width of a word. The strings "cafe" and "câfé" (appologies to all french
speaking people) have the same width on the sceen or printed. So those fancy
symbols are called "non-spacing".

HTH
Heinz
Heinz Ozwirk
2006-06-24 06:48:44 UTC
Permalink
Post by Robby
Hi,
============================================
DWORD dwBytesRead = 0;
BYTE abBuffer[100];
TCHAR szBuffer[100];
MySerial.Read(abBuffer,sizeof(abBuffer),&dwBytesRead);
============================================
Now, I need to print abBuffer to the screen, god knows I tried !
TextOut(hdc,100,100,abBuffer,100); //no good!
TextOut(hdc,100,100,TEXT(abBuffer),100); // no good!
TextOut(hdc,100,100,(char)abBuffer,100); //I didn't expect this one
to work!
TextOut(hdc,100,100,wsprintf(szBuffer,TEXT("%s")),abBuffer); //Forget it!
:(
By now I have looked for answers in Petzold, Osborn and SAM's books and I
now need help! >>>> a g a i n!
A book on C++ or even C might be usefull.
Post by Robby
BYTE is typedefed in Windows as so,
typedef unsigned char BYTE;
-so this tells me that a byte is really defined as a char... right ?
No, unsigned char. If it were simply char, there would have been some chance
that the compiler would have accepted ate least one of your attempts.
Post by Robby
-A char is 8 bits ... right ?
For existing versions of Windows and VC -- yes.
Post by Robby
So if the 4th parameter of TextOut takes a LPCTSTR, then how would I convert
this so that TextOut would accept it ?
That depends on whether you are compiling for Unicode or MBCS (and what
actually is in your BYTE array). When you are compiling for MBCS and your
array actually contains MBCS, you could cast the address of the first
element of the arrray to LPCSTR (using
reinterpret_cast<LPCSTR>(&abByte[0])). Also, when you are compiling for
Unicode and the array actually contains Unicode characters you could cast to
LPCWSTR using reinterpret_cast<LPCWSTR>. But if you are compiling for MBCS
and the array contains Unicode characters (or you are compiling for Unicode
and the array contains MBCS characters) you have to convert each character
in the array to the characterset expected by TextOut using functions like
MultiByteToWideChar (or WideCharToMultiByte).

On second thought, depending on the type of characters in the array you
could also use TextOutA (for single byte characters) or TextOutW (for
Unicode characters) instead of TextOut. In both cases you have to cast to
either LPCSTR or LPCWSTR (see above).

HTH
Heinz
Loading...