Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have a pMsg->wParam from a WM_KEYDOWN message, and I want to convert it into a CString. How can I do that?

I have tried the following code:

TCHAR ch[2];
ch[0] = pMsg->wParam;
ch[1] = _T('\0');
CString ss(ch);

but it does not work for high ASCII characters.

share|improve this question
3  
wParam and lParam are used in different ways depending on the message being passed. What message are you receiving here? If it a regular windows message (eg. WM_GETTEXT) or a custom one (anything greater than WM_USER). Can you supply more code to show the message being send and received? (Note that PostMessage and strings don't usually play well together if the string is on the stack, since by the time the recipient window gets it, the caller's stack may have been unwound and reused, leaving the pointer invalid.) –  BrendanMcK Feb 16 '12 at 7:35
    
@BrendanMcK i am using it on keystroke WM_CHAR basically, it is working fine on englisg language, but fails for language involving high ascii characters, may be the way i am terminating the TCHAR array is wrong for other languages –  Peter Feb 16 '12 at 8:06
    
Do you have UNICODE and _UNICODE defined for your project? If you don't, when TCHAR will be just a plain single ANSI char, so odd things may happen (though I think it should still work with high ASCII, unless your are using different code pages or something...). With UNICODE and _UNICODE defined, it should (AFAIK) work for anything (er, anything that UTF16 supports). Also, when you try a high-ASCII key, are you seeing the expected value for wParam in the debugger? –  BrendanMcK Feb 16 '12 at 8:35
    
unicode is defined in my project –  Peter Feb 16 '12 at 8:39
    
Did you check the wParam value you are receiving in the message using the debugger? If it is incorrect in the first place, then there is no way of converting it to a correct string :) Also, you mention 'postmessage' here - is this a normal WM_CHAR that is sent to your window as a result of a key press, or is it coming from other code? –  BrendanMcK Feb 16 '12 at 8:51

2 Answers 2

up vote 2 down vote accepted

The problem is that wParam contains a pointer to an array of characters. It is not a single character, so you can't create the string yourself by assigning it to ch[0] as you're trying to do here.

The solution turns out to be a lot easier than you probably expected. The CString class has a constructor that takes a pointer to a character array, which is precisely what you have in wParam.
(Actually, it has a bunch of constructors, one for pretty much everything you'll ever need...)

So all you have to do is:

CString ss(pMsg->wParam);

The constructor will take care of the rest, copying the string pointed to by wParam into the ss type.

share|improve this answer
    
i get an error saying more than one instance of constructor natches ... –  Peter Feb 16 '12 at 7:12
    
@Peter, try CString ss((LPCTSTR) pMsg->wParam);. –  Frédéric Hamidi Feb 16 '12 at 7:16
    
@Frédéric Hamidi the CString is always empty in this case –  Peter Feb 16 '12 at 7:27
1  
Sorry, but this is totally untrue. WM_CHAR sends a character in wParam, not a pointer. See msdn.microsoft.com/en-us/library/windows/desktop/…. This code worked probably because the constructor that takes a wchar_t was used in this case. –  kkm Feb 16 '12 at 14:25
1  
@kkm: Do note that my answer was written long before it was ever revealed in the comments that the message in question was WM_CHAR. The assumption I made was a very good one; just about every other window message sends a string of characters, rather than a single one. –  Cody Gray Feb 16 '12 at 18:27

According to the documentation, WM_CHAR sends a character code in wParam. The first paragraph in the Remarks section says that the code is indeed Unicode UTF-16 codepoint. This is same whether you are compiling your code for 8 or 16 bit TCHAR.

CodyGray's comment is correct in the part that CString supplies a variety of constructors. The one you are looking for is that which takes a wchar_t as its first argument (the second argument, the repetition count, is set to 1 by default). Therefore, to construct a CString out of a WPARAM, you cast the value to wchar_t. The following sample prints "0", confirming that the constructed string is indeed what it is expected to be.

#include <stdio.h>
#include <Windows.h>
#include <cstringt.h>
#include <atlstr.h>
int main ()
{
  WPARAM w = 0x222D;
  CString cs ((wchar_t)w);
  printf ("%d", cs.Compare (L"\x222D"));
}

It will work same and in both _UNICODE and ANSI compilation modes, and is portable accross 32 and 64 bitness.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.