【问题标题】:What's the preferred way for notifying a parent window from a customized control?从自定义控件通知父窗口的首选方式是什么?
【发布时间】:2012-03-15 15:21:31
【问题描述】:

我有一个超类标准控件的自定义 Windows 控件。我希望我的自定义控件通知其父窗口某些事件。这样做的最佳做法是什么?

  • 向父窗口发送WM_USERWM_APP 范围内的窗口消息。这将不起作用,因为如果另一个子控件尝试相同的操作,值可能会发生冲突。

  • 发送父窗口WM_NOTIFY。这似乎是正确的做法,但由于我正在扩展标准 Windows 控件,如何确保我使用的通知代码不会与基类(现在或将来)通常发送的通知代码冲突?

  • RegisterWindowMessage 向父窗口发送窗口消息。这应该足以避免意外冲突,但 Microsoft 建议仅将其用于进程间消息。

  • 让控件为应用程序提供一种机制来指定用于通知的WM_APP 消息。这似乎是唯一稳健的方法,但也感觉有点矫枉过正。 (或者,我认为应用程序可以传递一个函数指针,而不是指定窗口消息。)

我见过a similar question,但唯一的答案与 MFC 相关,并没有真正解决避免冲突的问题。

其他人通常会做什么?他们是否使用前三种方法之一而不担心它?我希望我的控件适合在我的应用程序之外更广泛地使用,所以我也更喜欢使用标准 Win32。

编辑:试图澄清我在寻找什么。

【问题讨论】:

  • 你的意思是子类吗?或者你正在使用ATL?您要转发什么样的消息?为什么?
  • @MikeKwan:超类或子类,这并不重要。但是出于这个问题的目的,您可以假设我正在超类化(即注册一个新的窗口类)。并假设我使用的是纯 Win32,所以没有 C++ 或 ATL/WTL。
  • 任何类库都努力通过将消息反射回原始控件来修复 borken C 消息传递模型。因此它可以由特定于控件实例的消息处理程序进行处理。通过 C++ 基类实现的通用行为,通过允许客户端代码派生来定制行为。没有理由在这里追求旧的方式,您只需不向父母发送消息就可以轻松得多。并自动解决歧义问题。

标签: winapi


【解决方案1】:

所以我注意到 CommCtrl.h 中定义的通知代码范围都是这样的:

#define NM_FIRST                (0U-  0U)       // generic to all controls
#define NM_LAST                 (0U- 99U)
...
#define TRBN_FIRST              (0U-1501U)       // trackbar
#define TRBN_LAST               (0U-1519U)

所以微软的通用控件至少有定义的范围(并且很可能总是很大的无符号值)。因此,如果我对标准控件进行超类或子类化并使用从 0 递增的通知代码,我认为我应该可以安全地抵御当前和未来版本的 Windows。

(如果我是从第三方控件派生的,那么这些第三方控件需要定义自己的保留范围。否则所有赌注都将失败。)

【讨论】:

    【解决方案2】:

    由于您正在对现有窗口类进行超类化并增强其行为,因此担心与现有消息发生冲突是正确的。因此,我觉得您必须使用WM_APP 范围内的消息。你同样可以使用RegisterWindowMessage,但我同意这太过分了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-09
      • 1970-01-01
      • 2013-10-01
      • 2017-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-19
      相关资源
      最近更新 更多