Really bad unicode problem with SendMessageW

This is a discussion on Really bad unicode problem with SendMessageW within the Windows Programming forums, part of the Platform Specific Boards category; ahh thanks, only problem now is that my whole app is unicode and its asking for alot of things and ...

  1. #16
    Registered User Rare177's Avatar
    Join Date
    May 2004
    Posts
    214
    ahh thanks, only problem now is that my whole app is unicode and its asking for alot of things and alot of the things like buttons and all that are not loading...ill go throu and make everything TCHAR and see if this helps , thanks

  2. #17
    Registered User Rare177's Avatar
    Join Date
    May 2004
    Posts
    214
    ok im not sure whats happening but i tried this
    Code:
    TCHAR re[128] = "RICHED20.DLL";
    LoadLibrary(re);
    it didnt look like it would work , should it?
    and if not is there something i should do so i dont have to go throu everything and do it like that.cheers

  3. #18
    the hat of redundancy hat nvoigt's Avatar
    Join Date
    Aug 2001
    Location
    Hannover, Germany
    Posts
    3,139
    What you really need to do is go through your code line by line. No exceptions, no shortcuts, no compiling to see if it magically works now.

    Every datatype that was char or any pointer variation of it needs to be TCHAR.

    Every string literal has to be enclosed in the TEXT or _T macro. No more "text", only _T( "text" ). Same goes for characters. No more 'c'. Only _T( 'c' ).

    Every function handling a string literal or character needs to be changed. If it is a library functions, there will be another function for unicode. It probably begins with _t. Look into the MSDN. Replace these functions.

    Get rid of any calculation assuming char has a sizeof 1. Get rid of any calculation assuming an array can hold as many characters as it's size.

    Do this line by line. I cannot stress this enough, no exceptions, no shortcuts, no compiling to see if it magically works now.

    If you did this, then your application will be ANSI and UNICODE compatible depending on your UNICODE/_UNICODE flags while compiling.

    Anything else will just result in a lot of headaches.
    hth
    -nv

    She was so Blonde, she spent 20 minutes looking at the orange juice can because it said "Concentrate."

    When in doubt, read the FAQ.
    Then ask a smart question.

  4. #19
    the hat of redundancy hat nvoigt's Avatar
    Join Date
    Aug 2001
    Location
    Hannover, Germany
    Posts
    3,139
    Code:
    HMODULE hModule = LoadLibrary( _T("RICHED20.DLL") );
    
    if( hModule == NULL )
    {
    // error, call GetLastError to get information
    }
    hth
    -nv

    She was so Blonde, she spent 20 minutes looking at the orange juice can because it said "Concentrate."

    When in doubt, read the FAQ.
    Then ask a smart question.

  5. #20
    Registered User Rare177's Avatar
    Join Date
    May 2004
    Posts
    214
    cheers
    ill go try this

  6. #21
    Registered User Rare177's Avatar
    Join Date
    May 2004
    Posts
    214
    ok it all seems good its now showing both ANSI and unicode full but theres 1 problem it wont resolve the host name/ip on the client..heres the code for it
    Code:
    int ConnectAndSend(){
    
    unsigned short port = 9980;
    int retval = 0;
    struct sockaddr_in server;
    WSADATA wsaData;
    SOCKET conns;
    struct hostent *hp;
    unsigned int addr;
    TCHAR server_name[50];
    
    retval = WSAStartup(0x202, &wsaData);
    
    if (retval != 0){
      AppendWindowText(hwndRichEdit, _T("ERROR: Cannot load winsock DLL.\r\n"));
      return 1;
    }
    
    AppendWindowText(hwndRichEdit, _T("> Winsock DLL loaded.\r\n"));
    
    SendMessage(hwndIPEdit, WM_GETTEXT, (WPARAM)ARRAYSIZE(server_name), (LPARAM)server_name);
    
    if (isalpha(server_name[0])) {
    
    	hp = gethostbyname(server_name);
    
    }else{
    
    	addr = inet_addr(server_name);
    	hp = gethostbyaddr((TCHAR*)&addr, 4, AF_INET);
    
    }
    
    if (hp == NULL){
      AppendWindowText(hwndRichEdit, _T("Can't resolve IP/Hostname. Please make sure it is correct.\r\n"));
      WSACleanup();
      return 1;
    }
    Last edited by Rare177; 06-02-2004 at 04:01 AM.

  7. #22
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Unfortunately, there are a few functions where a TCHAR version does not exist. Some of these functions only take unicode strings while others such as gethostbyname() and inet_addr() only take ansi strings. Therefore, you need to special case these functions. First, you need a good TCHAR to ansi conversion function:
    Code:
    BOOL TToAnsi(LPCTSTR szOriginal, LPSTR szAnsi, int cchAnsi)
    {
    #ifdef UNICODE
    	BOOL bRet = (0 != WideCharToMultiByte(CP_ACP, 0, szOriginal, -1, szAnsi, cchAnsi, NULL, NULL));
    #else
    	BOOL bRet = (NULL != lstrcpyn(szAnsi, szOriginal, cchAnsi));
    #endif
    	if (!bRet && cchAnsi > 0) szAnsi[0] = '\0';
    
    	return bRet;
    }
    Then you can use it:
    Code:
    if (SendMessage(hwndIPEdit, WM_GETTEXT, (WPARAM)ARRAYSIZE(server_name), (LPARAM)server_name))
    {
    	CHAR server_nameA[50];
    
    	// Convert down to ansi...
    	TToAnsi(server_name, server_nameA, ARRAYSIZE(server_nameA));
    
    	// Now use the A version where needed...
    	if (isalpha(server_nameA[0]))
    	{
    		hp = gethostbyname(server_nameA);
    	}
    	else
    	{
    		addr = inet_addr(server_nameA);
    		hp = gethostbyaddr((TCHAR*)&addr, 4, AF_INET);
    	}
    }
    The other alternative is to specifically use SendMessageA() to get an ansi string, but I think the conversion method can be cleaner.

    It should be noted that there is potential loss of information whenever unicode text is converted to ansi so this should be avoided when at all possible.

    P.S Please consider posting the compiler warning/error messages when you run into a problem.
    Last edited by anonytmouse; 06-02-2004 at 04:24 AM.

  8. #23
    Registered User Rare177's Avatar
    Join Date
    May 2004
    Posts
    214
    ok thanks
    got a few erros thou
    Code:
    hp = gethostbyaddr((TCHAR*)&addr, 4, AF_INET);
    assignment of pointer to const char to pointer to unsigned short
    Code:
    send(conns, SendBuffer, sizeof(SendBuffer), 0);
    assignment of pointer to const char to pointer to unsigned short
    Code:
    SOCKET conns;
    possible usage of conns before definition

  9. #24
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Quote Originally Posted by Rare177
    ok thanks
    got a few erros thou
    Code:
    hp = gethostbyaddr((TCHAR*)&addr, 4, AF_INET);
    assignment of pointer to const char to pointer to unsigned short
    Code:
    send(conns, SendBuffer, sizeof(SendBuffer), 0);
    assignment of pointer to const char to pointer to unsigned short
    Both of these functions take a const char * to signify that they take an array of bytes(rather than a string). Therefore, it is safe to cast:
    Code:
    hp = gethostbyaddr((const char *) &addr, 4, AF_INET);
    send(conns, (const char *) SendBuffer, sizeof(SendBuffer), 0);
    Code:
    SOCKET conns;
    possible usage of conns before definition
    Not sure what is going on here. Can you post the code where conns is actually used in the ConnectAndSend() function.

  10. #25
    Registered User Rare177's Avatar
    Join Date
    May 2004
    Posts
    214
    Code:
    int ConnectAndSend(){
    
    unsigned short port = 9980;
    int retval = 0;
    struct sockaddr_in server;
    WSADATA wsaData;
    SOCKET conns;
    struct hostent *hp;
    unsigned int addr;
    TCHAR server_name[50];
    
    retval = WSAStartup(0x202, &wsaData);
    
    if (retval != 0){
      AppendWindowText(hwndRichEdit, _T("ERROR: Cannot load winsock DLL.\r\n"));
      return 1;
    }
    
    AppendWindowText(hwndRichEdit, _T("> Winsock DLL loaded.\r\n"));
    
    SendMessage(hwndIPEdit, WM_GETTEXT, (WPARAM)ARRAYSIZE(server_name), (LPARAM)server_name);
    if (SendMessage(hwndIPEdit, WM_GETTEXT, (WPARAM)ARRAYSIZE(server_name), (LPARAM)server_name))
    {
    	CHAR server_nameA[50];
    
    	// Convert down to ansi...
    	TToAnsi(server_name, server_nameA, ARRAYSIZE(server_nameA));
    
    	// Now use the A version where needed...
    	if (isalpha(server_nameA[0]))
    	{
    		hp = gethostbyname(server_nameA);
    	}
    	else
    	{
    		addr = inet_addr(server_nameA);
    	hp = gethostbyaddr((const char *) &addr, 4, AF_INET);
    	}
    }
    
    
    if (hp == NULL){
      AppendWindowText(hwndRichEdit, _T("Can't resolve IP/Hostname. Please make sure it is correct.\r\n"));
      WSACleanup();
      return 1;
    }
    
     AppendWindowText(hwndRichEdit, _T("> Socket created.\r\n"));
    
    if (connect(conns, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR){
      AppendWindowText(hwndRichEdit, _T("ERROR: Cannot make remote connection.\r\n"));
      WSACleanup();
      return 1;
    }
    
    AppendWindowText(hwndRichEdit, _T("> Connected to ARCA server ...\r\n"));
    
    send(conns, (const char *) SendBuffer, sizeof(SendBuffer), 0);
    
    closesocket(conns);
    WSACleanup();
    
    AppendWindowText(hwndRichEdit, _T("\r\n> Command sent successfully.\r\n\r\n"));
    
    SendMessage(hwndReasonEdit, WM_SETTEXT, (WPARAM)0, (LPARAM)TEXT(""));
    SendMessage(hwndRemoteNameEdit, WM_SETTEXT, (WPARAM)0, (LPARAM)TEXT(""));
    
    return 0;
    }

  11. #26
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    You need a:
    Code:
    conns = socket(...);
    in there. Otherwise you pass a random uninitialised value to connect(), hence the warning. As far as I can see, you have not initialized server either.

  12. #27
    Registered User Rare177's Avatar
    Join Date
    May 2004
    Posts
    214
    thanks! got that working
    now theres 1 more thing
    the server is not accepting the data but other than that the client is free of errors

  13. #28
    Registered User Rare177's Avatar
    Join Date
    May 2004
    Posts
    214
    Code:
    	retval = recv(accepts, recv_buffer, ARRAYSIZE(recv_buffer), 0);
    assignment of pointer to const char to pointer to unsigned short

  14. #29
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Same as send() above. recv() expects a byte array, so cast to char *. Also, don't use ARRAYSIZE() here, as we need to pass the size of the buffer in bytes and not characters. So use sizeof(). I know, confusing!

    I'm off for now.

  15. #30
    Registered User Rare177's Avatar
    Join Date
    May 2004
    Posts
    214
    thank you soooo much i would probly be in a mental hospital if it wasnt for all of you help
    legends.

Page 2 of 2 FirstFirst 12
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Minor problem...bad stuff
    By beene in forum Windows Programming
    Replies: 19
    Last Post: 10-21-2006, 06:11 AM
  2. message box and unicode problem
    By Jumper in forum Windows Programming
    Replies: 2
    Last Post: 05-11-2004, 02:53 PM
  3. Replies: 5
    Last Post: 12-03-2003, 04:47 PM
  4. Cursor, UNICODE and VK's
    By GaPe in forum C Programming
    Replies: 10
    Last Post: 04-07-2002, 03:45 AM
  5. beginner problem
    By The_Nymph in forum C Programming
    Replies: 4
    Last Post: 03-05-2002, 04:46 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21