- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我创建了一个 Subclass 类,并在其中使用 SetWindowLongPtr()
将 GWLP_USERDATA
设置为包含指向我用来分发消息的派生类的指针。
所以如果我使用 SetWindowLongPtr(CurrentWindow, GWLP_USERDATA, (LONG_PTR)Data);
,我该如何恢复当我不再想继承旧数据时? MSDN 说初始值为零,所以我应该使用 SetWindowLongPtr(CurrentWindow, GWLP_USERDATA, (LONG_PTR)NULL);
函数吗?
编辑:实际上,我使用 SetProp、GetProp、RemoveProp 找到了解决此问题的方法,现在我不必担心会弄乱其他函数。下面是我的代码,供可能需要的人使用:
#ifndef WIN32_SUBCLASS_CLASS_H
#define WIN32_SUBCLASS_CLASS_H
#include <Windows.h>
#include <tchar.h>
class SubclassWindow
{
public:
static LRESULT CALLBACK stWinSubclassHandler(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
SubclassWindow* pWnd;
pWnd = (SubclassWindow*)GetProp(hwnd, TEXT("Subclass"));
if (pWnd)
return pWnd->WinSubclassHandler(hwnd, uMsg, wParam, lParam);
else
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
BOOL Subclass(SubclassWindow* Data, HWND hwnd)
{
if (Subclassed == TRUE || CurrentWindow != NULL)
return 0;
CurrentWindow = hwnd;
Subclassed = TRUE;
OriginalProc = (WNDPROC)GetWindowLongPtr(hwnd, GWL_WNDPROC);
SetProp(CurrentWindow, TEXT("Subclass"), (HANDLE)Data);
SetWindowLongPtr(CurrentWindow, GWL_WNDPROC, (LONG_PTR)SubclassWindow::stWinSubclassHandler);
return 1;
}
BOOL RemoveSubclass()
{
if (OriginalProc == NULL || CurrentWindow == NULL)
return 0;
Subclassed = FALSE;
RemoveProp(CurrentWindow, TEXT("Subclass"));
SetWindowLongPtr(CurrentWindow, GWL_WNDPROC, (LONG_PTR)OriginalProc);
return 1;
}
BOOL IsSubclassed() { return Subclassed; }
protected:
HWND CurrentWindow;
WNDPROC OriginalProc;
BOOL Subclassed;
SubclassWindow()
{
CurrentWindow = NULL;
OriginalProc = NULL;
Subclassed = FALSE;
}
virtual LRESULT CALLBACK WinSubclassHandler(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) = 0;
};
#endif
最佳答案
SetWindowLongPtr()
返回旧值,因此保存它,然后在稍后调用 SetWindowLongPtr()
删除子类时恢复它。
也就是说,为不是您自己创建的窗口替换 GWLP_USERDATA
是危险的。您不知道该窗口是否已将 GWLP_USERDATA
用于其自身目的。使用 SetWindowSubclass()
相反,它旨在解决该问题:
class SubclassWindow
{
public:
static LRESULT CALLBACK stWinSubclassHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
SubclassWindow* pWnd = (SubclassWindow*) dwRefData;
if ((pWnd) && (uIdSubclass == 1))
return pWnd->WinSubclassHandler(hwnd, uMsg, wParam, lParam);
else
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
BOOL Subclass(SubclassWindow* Data, HWND hwnd)
{
if (CurrentWindow != NULL)
return FALSE;
if (!SetWindowSubclass(hwnd, &stWinSubclassHandler, 1, (DWORD_PTR)Data))
return FALSE;
CurrentWindow = hwnd;
return TRUE;
}
BOOL RemoveSubclass()
{
if (CurrentWindow == NULL)
return FALSE;
if (!RemoveWindowSubclass(CurrentWindow, &stWinSubclassHandler, 1))
return FALSE;
CurrentWindow = NULL;
return TRUE;
}
BOOL IsSubclassed() { return (CurrentWindow != NULL); }
protected:
HWND CurrentWindow;
SubclassWindow()
{
CurrentWindow = NULL;
}
virtual LRESULT CALLBACK WinSubclassHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) = 0;
};
如果您的派生类需要默认处理任何给定的消息,您唯一需要做的改变就是让它们的 WinSubclassHandler()
实现调用 DefSubclassProc()
而不是 DefWindowProc()
(顺便说一句,调用的 API 是错误的 - 你应该调用 CallWindowProc(OriginalProc, ...)
而不是你之前的窗口过程子类替换有机会处理消息)。为此,我建议将该调用包装在您的 SubclassWindow
类中,以对后代隐藏该细节,例如:
class SubclassWindow
{
...
protected:
...
static LRESULT DefaultHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
...
};
class MySubclass : public SubclassWindow
{
protected:
virtual LRESULT CALLBACK WinSubclassHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
...
return DefaultHandler(hWnd, uMsg, wParam, lParam);
}
};
或者(这将允许后代更好地派生自后代):
class SubclassWindow
{
...
protected:
...
virtual LRESULT CALLBACK WinSubclassHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
...
};
class MySubclass1 : public SubclassWindow
{
protected:
virtual LRESULT CALLBACK WinSubclassHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
...
return SubclassWindow::WinSubclassHandler(hWnd, uMsg, wParam, lParam);
}
};
class MySubclass2 : public MySubclass1
{
protected:
virtual LRESULT CALLBACK WinSubclassHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
...
return MySubclass1::WinSubclassHandler(hWnd, uMsg, wParam, lParam);
}
};
class MySubclass3 : public MySubclass2
{
protected:
virtual LRESULT CALLBACK WinSubclassHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
...
return MySubclass2::WinSubclassHandler(hWnd, uMsg, wParam, lParam);
}
};
关于c++ - 不再需要在子类化后恢复 GWLP_USERDATA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18174566/
我最近更新了 ADT 插件,我的整个 Eclipse-Android 构建系统都停止工作了。从那以后,我尝试了我在互联网上可以找到的所有关于如何解决这个问题的方法。徒然。如果有人有确定的方法来解决此问
我已经知道有类似的话题,但对我来说没有任何帮助...... 这里是信息: 该应用程序始终在模拟器和设备上运行。我最近将该项目重命名为另一个名称。仍然工作得很好。今天我意识到它没有更改文件夹名称,然后它
在装有El Capitan的MacMini上,我无法再进行冲泡了。我收到以下错误: /usr/local/Library/Homebrew/config.rb:34:in `initialize':
是的,所以我不知道发生了什么。我一直在编写一个 AJAX 评论脚本,并且它可以工作,但它不再工作了。我从备份中恢复了它,以防万一我改变了任何东西,但没有运气。它转到表单的“操作”而不是 jQuery,
请原谅我的无能...我正在尝试在全局 var 阶段不再未定义后使用 Proxy 执行一些代码。这是我天真的尝试: ``` var stage = undefined let myObj; let st
我对 segues 了解不多,但我已经开始工作了..但突然间它不再工作了...... 我的代码似乎可以工作,但没有发生 segue: NSLog(@"login started"); if ([use
我已将以下重写规则添加到我的 web.config 中。它运行良好,阻止了所有提及的推荐垃圾邮件站点。然而,今天我突然注意到 social-buttons.com 突然出现在我的 Google Ana
在 C++ 中,可以在翻译单元中使用 static 关键字来影响符号(变量或函数声明)的可见性。 在 n3092 中,这已被弃用: Annex D.2 [depr.static] The use of
升级到 com.crashlytics.sdk.android:crashlytics:2.7.1@aar 后(从 2.6.8 开始),我无法再在 Firebase 应用中禁用 Crashlytics
您好,我遇到了一些障碍,我一直在为我的应用程序重新设计菜单导航。我设法做到了。但现在我的应用程序的一项功能已决定停止运行。 想法是你摇动你的手机,它会随机选择一张图片,与应用程序分开的代码工作正常,就
我有一行(容器)包含三个元素,我想水平显示它们之间的间距相等(并且行的左侧或右侧没有空格)。我正在使用带有 justify-content:space-between 的 flexbox。 这是在 F
直到最近,我才能够在 Windows 上使用 python 3.6.7 时安装 tensorflow 1.5.0 包。现在我不能,从下面的“来自版本”的消息来看,似乎根本没有可用的 tensorflo
不确定是否与最近的更新有关,但我突然无法在 Android Studio 编辑器中获得单行间距。如果我尝试将它更改为 1,它让我设置它,但当我按下“应用”时,它会迅速恢复为 1.5。用不同的字体试过,
我遵循了有关如何在 macOS 上安装 pip 的在线说明(例如 this、this 和 this)。 我看起来很简单,但它不适合我。 我的 python --version 是 2.7.10。 当我
Due to rounding errors, most floating-point numbers end up being slightly imprecise. https://www.flo
我试图让用户从他们在 Android 上的库中选择一张图片。但是当我使用 PictureChooser 插件时,它似乎不再起作用了 我看到这段代码可以工作,但现在不行了,我也不知道为什么。
自 .NET 4.5 起,Exception.HResult 的 setter/getter 现在是 public,但它曾经是 protected。 来自 MSDN: Starting with th
今天去处理一个较旧的 Python2.7 AppEngine 标准项目,但我似乎无法让端点工作。我下载了示例代码,看看我的项目是否是罪魁祸首,但该示例也不起作用。 https://cloud.goog
我是一名优秀的程序员,十分优秀!