我的程序已经设置为_UNICODE编译方式
程序中从一个文件读取了一段泰文到WCHAR类型的字串中,在AfxMessageBox()显示也能正确显示,但使用ExtTextOut或ExtTextOutW却不能正确显示。如果WCHAR类型的字串中的是中文,ExtTextOut或ExtTextOutW却能正确显示,为什么????,泰文怎样使用ExtTextOut或ExtTextOutW来显示呢???

解决方案 »

  1.   

    但是AfxMessageBox()显示是能正确显示的,而AfxMessageBox()最终也是调用ExtTextOutW进行输出的,可能AfxMessageBox对泰文进行了什么转换才通过ExtTextOutW输出的。
      

  2.   

    我只知道AfxMessageBox()最终是调用MessageBox()来显示的,至于MessageBox()中是用什么来显示的,不是很清楚,不过至少有三个函数可以达到同样的要求,ExtTextOut(),TextOut()和DrawText().如果你只是要弄清楚AfxMessageBox(),可以看MFC的源代码.
    如果要全部弄明白,我也说不清楚,不过你如果愿意,可把你的源码拿来看.([email protected]).
      

  3.   

    对于UNICODE 编码的字串显示,在win2000下大多最终都用ExtTextOutW()来显示。 我用钩子钩住了ExtTextOutW()函数,发现到了ExtTextOutW()后,字符串就与我原来送到AfxMessageBox()的不同了,每个字总是差了0x9cd!!,说明了系统进行了什么转换,谁能告诉我为什么?我给500分!!!!!
      

  4.   

    to Zark(金陵五月) 谢谢你,我整理一下,我给你发过去,不过你的机了要安装泰文的字库。我的泰文字串放在一个excel文件中。
      

  5.   

    MessageBox有MessageBoxA和MessageBoxW两版本的实现,实际上有你的代码页决定使用哪个版本.你试试将字符串改成: _T("你自己的字符串") 方式引用一下看看.注意T前面的下划线.
      

  6.   

    参看《WIndows编程》,有很详细的解释。都是宽字符惹的祸
      

  7.   

    我的原程序:
    _Application app;
          Workbooks books;
          _Workbook book;
          Worksheets sheets;
          _Worksheet sheet;
          Range range;
          Font font;
          Range cols;
     
          if(!app.CreateDispatch(_T("Excel.Application")))
          {
           AfxMessageBox(_T("Couldn't start Excel and get Application object."));
           return;
          }      
    books = app.GetWorkbooks(); COleVariant FilenameOpen(_T("d:\\dang.xls")), 
    UpdateLinks((short)0),
            
    Password(_T("")),
    WriteResPassword(_T("")),
    Delimiter (_T(",")),
            Origin((short)2), // xlWindows 
            Formats((short)5), 
            
            ConsecutiveDelimiter((long)FALSE, VT_BOOL), 
    ReadOnly((long)FALSE, VT_BOOL), 
            Editable ((long)FALSE, VT_BOOL), 
            IgnoreReadOnlyRecommended ((long)TRUE, VT_BOOL), 
            Notify((long)TRUE, VT_BOOL),
    AddToMru((long)FALSE, VT_BOOL),
            Converter((short)0);

    books.Open(_T("d:\\dang.xls"), UpdateLinks,ReadOnly,Formats,Password,WriteResPassword,
    IgnoreReadOnlyRecommended,Origin,Delimiter,Editable,Notify,Converter,AddToMru,AddToMru,AddToMru); 
    //const VARIANT& AddToMru, const VARIANT& Local, const VARIANT& CorruptLoad)
          book = books.GetItem(  COleVariant((short) 1));

     sheets =book.GetSheets();
          sheet = sheets.GetItem(COleVariant((short)1));
      range = sheet.GetRange(COleVariant(_T("A1")), COleVariant(L"A1"));
      COleVariant str,str1;

    wchar_t s1[300]=L"中国共产党",s2[300]=L"";

    short i=19;
        str=range.GetItem(COleVariant((short)i),COleVariant((short)1));
    wsprintf(s2,L"%s",(wchar_t*)(_bstr_t )str);  
    AfxMessageBox(s2);  //能正确显示
      
    HDC hdc=::GetDC(this->GetSafeHwnd());
    RECT ret;
    ret.left=0;
    ret.top=0;
    ret.right=300;
    ret.bottom=300;
    ExtTextOutW(hdc,20,70,ETO_CLIPPED,&ret,s1,wcslen(s1),NULL);//能正确显示
    ExtTextOutW(hdc,20,100,ETO_CLIPPED,&ret,s2,wcslen(s2),NULL); //显示乱码
      

  8.   

    注意,程序是在_UNICODE下编译的
      

  9.   

    很简单,你的设备所选择的字体中不包含泰文字UNICODE字符,看下面程序,哇,好激动,我真聪明:)
    CFont font;
    VERIFY(font.CreateFont(
    12,                        // nHeight
    0,                         // nWidth
    0,                         // nEscapement
    0,                         // nOrientation
    FW_NORMAL,                 // nWeight
    FALSE,                     // bItalic
    FALSE,                     // bUnderline
    0,                         // cStrikeOut
    ANSI_CHARSET,              // nCharSet
    OUT_DEFAULT_PRECIS,        // nOutPrecision
    CLIP_DEFAULT_PRECIS,       // nClipPrecision
    DEFAULT_QUALITY,           // nQuality
    DEFAULT_PITCH | FF_SWISS,  // nPitchAndFamily
    _T("Tahoma")));                 // lpszFacename
    CFont *pOldFont=pDC->SelectObject(&font);
    WCHAR str[256];
    FILE *pFile;
    pFile=fopen("E:\\aaa.txt","rb");//aaa.Txt中包含三个泰文字符
    int n=fread(str,sizeof(WCHAR),3,pFile);
    if(n>256)
    n=255;
    str[n]=0;
    pDC->TextOut(0,0,str);
    pDC->SelectObject(pOldFont);
    fclose(pFile);
      

  10.   

    to bluebohe(薄荷)
    谢谢!!我去试试,这500分,我一定给,还有一个问题:
    我用钩子钩住了ExtTextOutW()函数,发现到了ExtTextOutW()后,字符串就与我原来送到AfxMessageBox()的不同了,每个字总是差了0x9cd!!,说明了系统进行了什么转换,谁能告诉我为什么?我另给500分!!!!!
      

  11.   

    to  bluebohe(薄荷) 程序还是不行啊!!
    _Application app;
          Workbooks books;
          _Workbook book;
          Worksheets sheets;
          _Worksheet sheet;
          Range range;
          Font font;
          Range cols;
      long l;      // Start Excel and get Application object.
          if(!app.CreateDispatch(_T("Excel.Application")))
          {
           AfxMessageBox(_T("Couldn't start Excel and get Application object."));
           return;
          }      //Get a new workbook.
          books = app.GetWorkbooks();   COleVariant FilenameOpen(_T("d:\\dang.xls")), 
    UpdateLinks((short)0),
            
    Password(_T("")),
    WriteResPassword(_T("")),
    Delimiter (_T(",")),
            Origin((short)2), // xlWindows 
            Formats((short)5), 
            
            ConsecutiveDelimiter((long)FALSE, VT_BOOL), 
    ReadOnly((long)FALSE, VT_BOOL), 
            Editable ((long)FALSE, VT_BOOL), 
            IgnoreReadOnlyRecommended ((long)TRUE, VT_BOOL), 
            Notify((long)TRUE, VT_BOOL),
    AddToMru((long)FALSE, VT_BOOL),
            Converter((short)0);
    books.Open(_T("d:\\dang.xls"), UpdateLinks,ReadOnly,Formats,Password,WriteResPassword,
    IgnoreReadOnlyRecommended,Origin,Delimiter,Editable,Notify,Converter,AddToMru,AddToMru,AddToMru); 

          book = books.GetItem(  COleVariant((short) 1));

     sheets =book.GetSheets();
          sheet = sheets.GetItem(COleVariant((short)1));
      range = sheet.GetRange(COleVariant(_T("A1")), COleVariant(L"A1"));
      COleVariant str,str1;  
    wchar_t s1[300];  
    short i = 19;
             str=range.GetItem(COleVariant((short)i),COleVariant((short)1));
     str1=range.GetItem(COleVariant((short)i),COleVariant((short)2));

    wsprintf(s1,L"%s",(wchar_t*)(_bstr_t )str);
    AfxMessageBox(s1); //正确显示
    CDC *pDC = GetDC();
    CFont font1;
    VERIFY(font1.CreateFont(
    12,                        // nHeight
    0,                         // nWidth
    0,                         // nEscapement
    0,                         // nOrientation
    FW_NORMAL,                 // nWeight
    FALSE,                     // bItalic
    FALSE,                     // bUnderline
    0,                         // cStrikeOut
    ANSI_CHARSET,              // nCharSet
    OUT_DEFAULT_PRECIS,        // nOutPrecision
    CLIP_DEFAULT_PRECIS,       // nClipPrecision
    DEFAULT_QUALITY,           // nQuality
    DEFAULT_PITCH | FF_SWISS,  // nPitchAndFamily
    _T("Tahoma")));                 // lpszFacename
    CFont *pOldFont=(CFont *)pDC->SelectObject(&font); RECT ret;
    ret.left =0;
    ret.top=0;
    ret.right=240;
    ret.bottom=250;
    ExtTextOutW(pDC->GetSafeHdc(),00,0,ETO_CLIPPED,&ret,s1,wcslen(s1),NULL);//不能正确显示
    pDC->SelectObject(pOldFont);
      

  12.   

    老兄,好象你犯了个错误啊,wsprintf(s1,L"%s",(wchar_t*)(_bstr_t )str);其中"%S"或者"%ls"或"lS"才允许传给unicode字符串。而你是在没有#define UNICODE的情况下使用,所以"%s"只能接受一般的字符串这样你把unicode串传进来,用普通字符串保存,当然结果不正确了!!!!接分!!!
      

  13.   

    我已经测试过了,没问题才拿上来的,可能是Tahoma中也不包含所有的泰文,你再检查一下你的程序吧
      

  14.   

    我的建议是你直接写一个泰文UNICODE文件(通过字符映射表找),拷贝到文本文件中,然后用UNICODE方式保存,用UEDIT把文本文件的前两个字符删掉(FF EF,UNICODE文件头),保存,读区这个文件中的数据,显示
      

  15.   

    to honglunxu() 
    你没有看清楚,我是用_UNICODE方式编译的,所以不用"%ls"或"lS"也能传给unicode字符串
      

  16.   

    to bluebohe(薄荷):
    我再研究研究!!
      

  17.   

    UNICODE字符串拥有很多Code page, 有可能在Unicode串中有不同的语言的字符串(比如混合了泰文,中文,日文,英文等等),每种语言有不同的Code page, 如果想正确显示不同语言的字体,防止乱码出现,关键是能够找到Unicode字符串中的所有的code page, 然后根据code page 选择字符集; 可以看一下win2000的notepad, 它对Unicode的支持就很好,UtrlEdit不能显示的Unicode串在notepad里面可以完全无误的现实。
        处理这种问题不需要用_UNICODE方式编译。系统本身提供了接口,(IMLangCodePages),可以对任何Unicode字符串计算其Code page, 并能够获得字符串中不同Code page的字符串长度, 然后再选择字符集输出即可。我曾经给公司写过UNICODE Edit, 就用这种方式,在任何系统下,输入各种文字都可以正确的输出和显示,前提是系统必须安装了这种字体,也就是说支持这种字符集。
        因为系统默认code page 是 local code page, 显示中文自然没有问题;系统在输出时绝不仅仅是调用谋个函数就搞定的,否则其提供的Interface是多余的。
        具体用法可以看MSDN。
      

  18.   

    程序收到,在我的机器(WINDOWS XP, ENGLIGH)上,似乎对EXCEL的COM方法支持不够.所以
    app.CreateDispatch(_T("Excel.Application"));
    这句失败,因此无法测试,如果你能重写一个用文件加载泰文字串而不是用EXCEL加载的测试程序,再发过来,那就更好了.我在你的基础上写一个用文件加载泰文字串方法,显示结果正常.从你的源码来看,并无明显的错误.我认为这个问题的原因多半在于机器的设定以及对话框的缺省字体这两方面.在我的机器,LOCALE是China,语言是Engligh,没有改你的对话框任何设置.加载两个txt文件,UNICODE存贮方式,一个是泰文,一个是中文.所有显示都是正确的.
      

  19.   

    to MarginLi() :
    非常感谢您的提示,您好的提示对我确实很有用。但现在还有点问题请教:
    我想在API钩子中使用IMLangCodePages,但编译不通过,是不是在API钩子中不能使用IMLangCodePages??,相同的程序在普通的程序确能正常编译和运行。有没有与IMLangCodePages功能相同的直接的API调用??
    谁能解决这个问题,我出500分!!
    to bluebohe(薄荷):
    问题还没有能解决,还不能结,我开新贴子给你分!
    http://expert.csdn.net/Expert/topic/2462/2462463.xml?temp=7.893008E-02
    http://expert.csdn.net/Expert/topic/2462/2462464.xml?temp=.9308893
      

  20.   

    我觉得在钩子中还是可以使用IMLangCodePages的,应该是程序的问题,能吧你的程序发给我吗?[email protected]
    另外,既然你的程序都编译成_UNICODE版本的了,还要代码页何用?
      

  21.   

    字符串最好要显示的复制使用:
    lstrcpy()