Winapi 如何测试自定义回调是否设置为给定窗口的当前过程?

Winapi 如何测试自定义回调是否设置为给定窗口的当前过程?,winapi,windows-mobile,function-pointers,unmanaged,kiosk-mode,Winapi,Windows Mobile,Function Pointers,Unmanaged,Kiosk Mode,我们有一个适用于Windows Mobile 5的亭模式应用程序,它至少在一年的生产中表现强劲。它通过windows API函数使用窗口子类化来覆盖任务栏的行为,以防止用户离开我们的应用程序或其他明确允许的应用程序 我的回调会覆盖一些窗口消息的处理,并调用其他消息的默认处理程序。这是通过存储由SetWindowLong返回的上一个函数指针,并在新函数中调用CallWindowProc来实现的 然后我们不得不更新应用程序,使其与WindowsMobile 6.5.3兼容,并开始出现一系列问题。我随

我们有一个适用于Windows Mobile 5的亭模式应用程序,它至少在一年的生产中表现强劲。它通过windows API函数使用窗口子类化来覆盖任务栏的行为,以防止用户离开我们的应用程序或其他明确允许的应用程序

我的回调会覆盖一些窗口消息的处理,并调用其他消息的默认处理程序。这是通过存储由
SetWindowLong
返回的上一个函数指针,并在新函数中调用
CallWindowProc
来实现的

然后我们不得不更新应用程序,使其与WindowsMobile 6.5.3兼容,并开始出现一系列问题。我随后禁用了6.5上新增的底部菜单按钮。在单个应用程序上,它工作正常,菜单尊重我的回调。当用户通过我们的应用程序打开另一个应用程序时,该窗口似乎被重新创建,我必须设计一种机制来检测前景窗口的变化,然后再次“重新分类”该窗口

在我的代码中,我无法控制何时重新创建此窗口,因此我的第一次尝试是使用
GetWindowLong
函数获取当前回调地址,并根据我自己的函数地址对其进行测试。我学到了一个艰难的方法,那就是我不能仅仅比较那样的值,因为

因为我无法以这种方式测试我的方法是否是当前处理程序,所以有时我会将我的方法设置为处理程序,而前一个处理程序也是我自己的方法(在本例中,窗口没有重新创建,因此已经设置了我的方法)。这会导致无限循环,因为我的回调最终会无限期地调用自己


如何知道我的自定义函数是否是某个窗口正在使用的函数,以便避免这种无限递归?

将自定义消息发送到窗口。在自定义函数中处理此消息,以返回一些值,指示它是自定义处理程序。。等等

if(SendMessage(hwnd, mymsg, 0, 0) != myvalue)
    ;// It's not your handler

将自定义消息发送到窗口。在自定义函数中处理此消息,以返回一些值,指示它是自定义处理程序。。等等

if(SendMessage(hwnd, mymsg, 0, 0) != myvalue)
    ;// It's not your handler

将自定义消息发送到窗口。在自定义函数中处理此消息,以返回一些值,指示它是自定义处理程序。。等等

if(SendMessage(hwnd, mymsg, 0, 0) != myvalue)
    ;// It's not your handler

将自定义消息发送到窗口。在自定义函数中处理此消息,以返回一些值,指示它是自定义处理程序。。等等

if(SendMessage(hwnd, mymsg, 0, 0) != myvalue)
    ;// It's not your handler

不要使用
SetWindowLong(GWL\u WNDPROC)
对窗口进行子类化。改为使用(如Raymond Chen所说):

除了提供更安全的子类语义(例如一次允许多个子类)之外,它还允许您将用户定义的数据与每个子类相关联。因此,您可以使用检查是否已经对窗口进行了子类化


或者,您可以简单地跟踪是否已经对窗口进行了子类化。一个简单的布尔变量就足够了。一旦您的子类就位,您必须在窗口完全销毁之前删除该子类。因此,例如,当子类收到
WM\u NCDESTROY
消息时,您可以删除子类并同时清除布尔值,然后下次再次看到窗口时,布尔值将告诉您需要对窗口进行子类化。

不要使用
SetWindowLong(GWL\u WNDPROC)
对窗口进行子类化。改为使用(如Raymond Chen所说):

除了提供更安全的子类语义(例如一次允许多个子类)之外,它还允许您将用户定义的数据与每个子类相关联。因此,您可以使用检查是否已经对窗口进行了子类化


或者,您可以简单地跟踪是否已经对窗口进行了子类化。一个简单的布尔变量就足够了。一旦您的子类就位,您必须在窗口完全销毁之前删除该子类。因此,例如,当子类收到
WM\u NCDESTROY
消息时,您可以删除子类并同时清除布尔值,然后下次再次看到窗口时,布尔值将告诉您需要对窗口进行子类化。

不要使用
SetWindowLong(GWL\u WNDPROC)
对窗口进行子类化。改为使用(如Raymond Chen所说):

除了提供更安全的子类语义(例如一次允许多个子类)之外,它还允许您将用户定义的数据与每个子类相关联。因此,您可以使用检查是否已经对窗口进行了子类化


或者,您可以简单地跟踪是否已经对窗口进行了子类化。一个简单的布尔变量就足够了。一旦您的子类就位,您必须在窗口完全销毁之前删除该子类。因此,例如,当子类收到
WM\u NCDESTROY
消息时,您可以删除子类并同时清除布尔值,然后下次再次看到窗口时,布尔值将告诉您需要对窗口进行子类化。

不要使用
SetWindowLong(GWL\u WNDPROC)
对窗口进行子类化。改为使用(如Raymond Chen所说):

除了提供更安全的子类语义(例如一次允许多个子类)之外,它还允许您将用户定义的数据与每个子类相关联。因此,您可以使用检查是否已经对窗口进行了子类化

或者,您可以简单地跟踪是否已经对窗口进行了子类化。一个简单的布尔变量就足够了。一旦您的子类就位,您必须在窗口完全销毁之前删除该子类。例如,当子类收到<