Winapi 控件为Unicode或ANSI意味着什么?

Winapi 控件为Unicode或ANSI意味着什么?,winapi,unicode,ansi,Winapi,Unicode,Ansi,Windows控件可以是Unicode或ANSI,我的问题是,控件属于这两类中的一类意味着什么 是否为以下内容(如果我假设控件为Unicode): 控件的缓冲区是Unicode格式的 WM_CHAR消息以Unicode格式发送(例如,“A”以0x0041而不是0x41的形式发送) 这意味着发送到窗口过程的窗口消息将是ANSI或Unicode版本。例如,Unicode窗口将在WM_CREATE中接收一个,而ANSI窗口将接收一个CREATESTRUCTA 这将适用于几乎所有包含字符串数据的窗口消

Windows控件可以是Unicode或ANSI,我的问题是,控件属于这两类中的一类意味着什么

是否为以下内容(如果我假设控件为Unicode):

  • 控件的缓冲区是Unicode格式的
  • WM_CHAR消息以Unicode格式发送(例如,“A”以0x0041而不是0x41的形式发送)

    • 这意味着发送到窗口过程的窗口消息将是ANSI或Unicode版本。例如,Unicode窗口将在
      WM_CREATE
      中接收一个,而ANSI窗口将接收一个
      CREATESTRUCTA

      这将适用于几乎所有包含字符串数据的窗口消息

      Windows将相应地在内部封送数据。例如,如果您将ANSI
      SendMessageA(WM_SETTEXT,…)
      调用到Unicode窗口,该窗口将接收带有Unicode字符串的消息

      窗口将是Unicode或ANSI,这取决于它的类是注册到还是。您可以通过调用来测试窗口是否为Unicode


      一些关于常用控件的信息,因为这似乎就是你所说的

      首先,ANSI窗口作为Unicode窗口的父窗口没有问题。还要记住,“控件”只是窗口

      常用控件总是Unicode。他们收到的消息将采用本机Unicode格式。当然,您不会看到它,因为它都是操作系统内部的(例外:如果您将公共控件子类化)

      您通常处理的消息将以
      WM_命令
      或的形式发送到您的窗口。这些消息从常用控件发送到其父窗口(您的窗口)。他们将尊重您的Unicode或ANSI窗口,如下所示:

    • 首先,他们会向您的窗口发送一条消息,询问您是否希望以ANSI或Unicode格式接收消息(尽管您的窗口是Unicode或ANSI格式)
    • 如果不处理WM_NOTIFYFORMAT,则控件将调用
      IsWindowUnicode
      来确定
    • 然后控件将相应地发送消息
    • 因此,基本上,您不需要知道公共控件是否为Unicode,因为1)它始终是Unicode,2)这个问题只与处理消息有关,这是Windows内部的,而不是您的责任


      您的责任是处理从通用控件发送到您自己窗口的通知。在这种情况下,您自己窗口的Unicode/ANSI特性才是最重要的。

      我不知道“控件缓冲区”是什么意思,但我想我还是给出了一个全面的解释。我指的是分配用于保存控件数据的内存,例如,“编辑”控件缓冲区保存将在控件中绘制的字符串。因此,如果控件是Unicode,则缓冲区将被视为Unicode(每2个字节将映射到1个字符)。此“缓冲区”与窗口是否为Unicode无关。您所说的缓冲区是控件的内部,从Unicode窗口的概念中抽象出来。Unicode窗口只涉及传递到其窗口进程的消息。然后控件对该数据执行的操作是一个黑盒。在我的回答中,我谈到了
      WM_SETTEXT
      的情况,我想这就是你所说的。谢谢你的澄清。因此,从理论上讲,即使我有一个ANSI“编辑”控件,我也不应该假设内存中的字符串将表示为每个字符1个字节,Windows可以随意表示它(每个字符可能有4个字节!)。我的假设正确吗?或者在问更多问题之前,我应该对这个问题进行更多的调查吗?我在回答中添加了一整节关于常见控件和家长的内容。
      WM_SETTEXT
      的数据确实是经过整理的。然而,您给出的示例演示了数据转换。也许你可以更新答案,分别解释每个概念。关于
      WM\u NOTIFY
      的附加说明解释了为什么需要
      WM\u NOTIFYFORMAT
      (通知发送到控件的父级)将进一步改进已经很好的答案。这并不完全正确!Windows不会为您进行任何正确编码的编组。如果它是ANSI控件,并且您像查询宽字符一样查询它,那么您将失望地得到垃圾。RichText v2控件就是一个例子,它有RichText20A和RichText20W版本,为了获得文本,您需要传递正确的ANSI或宽字符结构TEXTRANGEA/TEXTRANGEW。如果您将TEXTRANGEA发送到RichText20W,您将得到垃圾或什么都没有,反过来也是一样。