1

我有一个代表文本框的类,在类的构造函数中我调用了CreateWindow函数,并且我想在额外的窗口内存中存储指向该对象的指针,所以在WndProc函数中我将获取指针,并将使用班级成员。
我试图用这段代码做到这一点,但它不工作,有人可以写一个例子来做到这一点:

  • 我应该在结构cbWndExtra成员中赋予什么价值WNDCLASSEX
  • 怎么打电话SetWindowLong
  • 怎么打电话GetWindowLong

我写的代码:

  wcex.cbWndExtra   = 4;

我在文本框类的构造函数中写了这个:

  hWnd = CreateWindow(...);
  SetWindowLong(hWnd,0,(LONG)this);

这在WndProc函数 中

  unique_ptr<TextBox> pTextBox;
  pTextBox.reset((TextBox*)GetWindowLong(hWnd,0));

=== 编辑 ===

现在我看到,如果我将WndProc函数中的代码更改为以下代码:

 TextBox *pTextBox;
 pTextBox = (TextBox*)GetWindowLong(hWnd,0);

它也可以,但是用unique_ptr它不起作用。

4

1 回答 1

2

来自“SetWindowLong”的 MSDN 文档,关于“索引”参数。

要设置的值的从零开始的偏移量。有效值的范围是零到额外窗口内存的字节数减去整数的大小。要设置任何其他值,请指定以下值之一。

只要您在 WNDCLASS 结构中创建了具有至少该数量的“cbWndExtra”的窗口,正偏移量就可以指向任何字节偏移量。

我怀疑这种情况下的问题可能与指针的大小有关。您在窗口结构的末尾显式分配了 4 个额外字节,但如果您在 64 位系统上,则指针大小将为 8。这可以解释它有时有效,有时无效。(如果高位字恰好全为零,即使地址被截断,它也可能起作用。)如果是这种情况,您需要在两个单独的调用中设置高位字和低位字,或者最好使用64 位变体“SetWindowLongPtr”。

这是一个简单的示例,它使用此功能将两个指针存储在 windows 额外数据区域中(注意以下内容适用于 32 位和 64 位)

wndclass.cbWndExtra = sizeof(char*) * 2; // Reserve space for 2 pointers.

然后稍后设置一个值:

SetWindowLongPtr(hwnd, 0, (LONG_PTR)firstPtr);
SetWindowLongPtr(hwnd, sizeof(char*), (LONG_PTR)secondPtr); // Index is byte offset.

并使用以下方法检索值:

LONG_PTR firstPtr = GetWindowLongPtr(hwnd, 0);
LONG_PTR secondPtr = GetWindowLongPtr(hwnd, sizeof(char*));

但是,如果您只需要存储一个指针,则可以不设置任何额外内存,将 cbWndExtra 保留为零,然后将 GWLP_USERDATA 作为索引传递。与其他预定义值一样,GWLP_USERDATA 是“向后”到类/窗口数据的负偏移量。它是为这种目的保留的空间,但它只能容纳一个指针的数据。

于 2017-07-03T10:21:04.240 回答