none
MFC 非模态对话框处理TAB键后编辑框乱码 RRS feed

  • 问题

  • 从MFC DLL中加载一个无模式对话框时,TAB键无法使焦点在控件之间移动,MS给出了如下解决方法:http://support.microsoft.com/kb/233263/en-us

    但是使用了这种方法之后发现,对话框上的编辑框在输入中文时会乱码,经过调查发现乱码原因是汉字两个字节的编码只有一个字节发送到了编辑框,但是为什么会丢失一个字节则原因不明,请教各位如何解决呢?

    谢谢各位相助!

    2011年4月19日 7:41

答案

  • 您将您的工程修改为Unicode编码试试~


    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.
    2011年4月21日 2:55
    版主
  • Hi singuo,

    请问你在没使用这个方法时是否会出现这个问题。

    另外,请您现在把这个方法从您的程序中删去,看是否还有这个问题。

    您还可以尝试以下几个方法试试:

    1.       重复输入几次,看看是否还有这个问题;

    2.       如果您有用到createdialog的话,请您改成dialogbox试试;

    3.       请您把您的MFC工程的Property/Configuration Properties/General 中的Character Set 改成”Use Multi-Byte Character Set” 再编译运行下,看看是否有这个问题;

    4.       设置控制面版的 "区域和语言 ",看看 是否还有这个问题;

     

    Lucy


    Lucy Liu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年4月20日 9:35
    版主
  • 你好,

    如果在if条件里跳过对WM_CHAR的处理, 会有怎么样的结果?例如:

    if ( (lpMsg->message >= WM_KEYFIRST && lpMsg->message <= WM_KEYLAST && lpMsg->message != WM_CHAR) )

     

    Yi


    Yi Feng Li [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年4月25日 6:17
    版主

全部回复

  • Hi singuo,

    请问你在没使用这个方法时是否会出现这个问题。

    另外,请您现在把这个方法从您的程序中删去,看是否还有这个问题。

    您还可以尝试以下几个方法试试:

    1.       重复输入几次,看看是否还有这个问题;

    2.       如果您有用到createdialog的话,请您改成dialogbox试试;

    3.       请您把您的MFC工程的Property/Configuration Properties/General 中的Character Set 改成”Use Multi-Byte Character Set” 再编译运行下,看看是否有这个问题;

    4.       设置控制面版的 "区域和语言 ",看看 是否还有这个问题;

     

    Lucy


    Lucy Liu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年4月20日 9:35
    版主
  • Morning Lucy,

    谢谢您的回答。

    没有使用这个方法之前是没有问题的,把方法删掉也不会有问题,只是快捷键会无效。

    1. 连续输入相同的字符,有些时候是正确的,但没有规律。但是每次重新输入,一定会乱码;
    2. 由于功能要求对话框时modeless的,所以只能使用Create方法;
    3. 字符集当前选项正是“使用多字节字符集”;
    4. 控制面板“区域和语言”设置和程序是符合的,仍然有乱码问题。

    我使用 TRACE 打印了进入

    if ( (lpMsg->message >= WM_KEYFIRST && lpMsg->message <= WM_KEYLAST) )

    分支中的每一条消息,然后运行程序,在编辑框输入一个中文,现象如下:

    • 注释掉 IsDialogMessage,连续出现两个 WM_CHAR,wParam的值分别是中文编码的高低字节,不乱码;
    • 保留 IsDialogMessage,只出现一个 WM_CHAR,是编码的高字节,低字节丢失,乱码。

    再次感谢您的回复。

    2011年4月21日 2:17
  • 您将您的工程修改为Unicode编码试试~


    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.
    2011年4月21日 2:55
    版主
  • 不能修改为Unicode :(

    这个工程是一个解决方案的一部分,整个解决方案都使用多字节编码,而且编写的时候并没有考虑unicode,如果更改编码设置,几乎所有代码都要改动。

    2011年4月21日 5:19
  • Hi singuo,

    请您尝试用IsDialogMessageW,这个函数和IsDialogMessageA函数功能一样,不过IsDialogMessageW用于Unicode编码,而IsDialogMessage用于ANSI编码。

     

    Lucy


    Lucy Liu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年4月22日 7:49
    版主
  • 我按照您说的使用了IsDialogMessageW,依然乱码。 工程是ANSI编码的,应该不能使用UNICODE版本的API吧。 我觉得可能问题不在于使用了哪种编码,而是IsDialogMessage对消息的处理流程出了什么问题,导致消息并没有正确传递,最终editbox没有收到完整的编码,毕竟不论是ANSI还是UNICODE,都是能正常表示汉字的。 这个问题好像大家遇到的不多,谢谢楼上所有热心的回复:),希望能尽快找到方法。
    2011年4月25日 3:03
  • 你好,

    如果在if条件里跳过对WM_CHAR的处理, 会有怎么样的结果?例如:

    if ( (lpMsg->message >= WM_KEYFIRST && lpMsg->message <= WM_KEYLAST && lpMsg->message != WM_CHAR) )

     

    Yi


    Yi Feng Li [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年4月25日 6:17
    版主
  • 如果跳过 WM_CHAR,不会乱码,但部分快捷键会失效。

    比如一个快捷键为A的checkbox,当它获取焦点时,原本单独按下A键就可以选中和取消,现在只有按下Alt-A才可以。

    2011年4月25日 8:56
  • 由于IsDialogMessage自己会处理消息转换换,我们不能把TranslateMessage 和 DispatchMessage处理过的消息传入IsDialogMessage。 我们知道一个键盘所产生的WM_CHAR是由WM_KEYUP和WM_KEYDOWN产生的,所以可能出现问题。详细请查看文档:http://msdn.microsoft.com/en-us/library/ms645498(v=vs.85).aspx

    我建议跳过WM_CHAR消息处理。对于快捷键的处理,直接响应WM_KEYDOWN消息而不是处理WM_CHAR。


    Yi Feng Li [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年4月25日 14:29
    版主
  • Hi Yi Feng:

    我解释一下为什么调用IsDialogMessage。

    IsDialogMessage是处理对话框消息最合适的方法,由windows来分析当前消息是否可以直接或者通过转换构成快捷键。正常情况下对话框程序的消息循环就是用这个API来处理对话框特有的快捷键的,比如TAB。

    现在程序里的一个对话框是在MFC DLL中实现的,MFC没有为DLL中实现的对话框调用IsDialogMessage,所以快捷键无效,为此MS提供了一个方法http://support.microsoft.com/kb/233263/en-us,手工调用IsDialogMessage解决此问题。

    手工调用之后快捷键问题解决,但是引入了另一个问题,就是输入汉字会乱码,如果用SDK编写一个对话框程序,在消息循环中调用IsDialogMessage,是没有问题的。

    您提到的IsDialogMessage对消息的转换问题,MS的方法里也处理了,当IsDialogMessage返回非零值表明它处理了这条消息后,消息被重置,后续的流程不会再重复处理。

    如果自行分析WM_KEYDOWN来实现快捷键,很难保证能正确判断所有的快捷键。

    新找到一篇文章,http://hi.baidu.com/%CF%B5%B4%C7%CF%C2%B4%CE/blog/item/8da223852ac862cdbc3e1e9d,可能与此问题有关,供参考。

    谢谢您的回复!

    2011年4月26日 2:20
  • Hi singuo,

    请您尝试不用键盘的快捷键,选择以下方法来代替:

    在您的工程的Resource View 窗口下,右键您的.rc 文件,选择Add Resource

    在弹出的Add Resource对话框中选择Accelerator,点击New

    Accelerator资源中,您就可以选择KeyType等,还可以增加Event Handler(右键选择Add Event Handler…;

    这样传递的就不是WM_CHAR 而是WM_COMMAND.

     

    谢谢,

    Lucy


    Lucy Liu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年4月27日 7:58
    版主
  • Morning Lucy,

    使用加速键的确可以绕过这个问题,不过这种方法不是很现实,因为有很多对话框有同样的问题,改造和测试工作量非常大。

    再者,程序中模态对话框没有此问题,控件快捷键都是字母加下划线的形式,需要尽量保持统一。

    我们一直在寻找一个能解决这个问题的方法,尽量不要绕过它:)

    感谢大家的持续关注!

    2011年4月28日 1:05