[英]Why does calling GetWindowRect with pointer cause exception but address doesn't
I have a utility function in a dll to center my form on the host applications screen. 我在dll中有一个实用程序功能,可将窗体放在主机应用程序屏幕上。 I'm using RAD Studio XE2.
我正在使用RAD Studio XE2。 I have to do it manually because the host application is non-VCL and the form placement parameters of the TForm don't work properly.
我必须手动执行此操作,因为主机应用程序是非VCL并且TForm的表单放置参数无法正常工作。 The code below works.
下面的代码有效。 Both functions are declared static, and I've previously set the Application handle property to the host app.
这两个函数都声明为静态,并且我之前已将Application handle属性设置为主机应用程序。
void MyClass::GetAppCenter(POINT * pos) {
RECT Rect;
GetWindowRect(Application->Handle, &Rect);
pos->x = (Rect.left + Rect.right) / 2;
pos->y = (Rect.top + Rect.bottom) / 2;
}
void MyClass::PlaceForm(TForm * f) {
POINT pos;
GetAppCenter(&pos);
for (int i = 0; i < Screen->MonitorCount; i++) {
TRect r = Screen->Monitors[i]->WorkareaRect;
if (r.Contains(pos)) {
f->Left = (r.Left + r.Right) / 2 - f->Width / 2;
f->Top = (r.Top + r.Bottom) / 2 - f->Height / 2;
return;
}
}
}
My initial GetAppCenter code used a Rect * instead and returned the correct value, but threw an Access Violation exception when I set f->Left. 我最初的GetAppCenter代码使用Rect *代替并返回正确的值,但是当我设置f-> Left时抛出了访问冲突异常。 Can anyone explain why?
谁能解释为什么?
// original version
void OasisUtils::GetOasisCenter(POINT * pos) {
RECT *Rect;
GetWindowRect(Application->Handle, Rect);
pos->x = (Rect->left + Rect->right) / 2;
pos->y = (Rect->top + Rect->bottom) / 2;
delete Rect; // tried with and without this
}
RECT *Rect;
GetWindowRect(Application->Handle, Rect);
//Rect->left
This is incorrect. 这是不正确的。
GetWindowRect
needs a valid RECT*
argument so that it fills memory pointed to by this pointer. GetWindowRect
需要一个有效的RECT*
参数,以便它填充此指针指向的内存。 You are instead passing an uninitialized pointer expecting that some magic will make it valid. 相反,您传递的是未初始化的指针,期望有某种魔术使之有效。 Instead you are getting access violation.
相反,您遇到访问冲突。 You need:
你需要:
RECT Rect;
GetWindowRect(Application->Handle, &Rect); // <<--- Note &
//Rect.left
GetWindowRect expects the caller to own the rectangle structure. GetWindowRect期望调用方拥有矩形结构。
In your original version, your *Rect
does not point to any valid memory. 在您的原始版本中,您的
*Rect
不会指向任何有效的内存。 So when you try to use it, you're accessing some random block of memory that you don't own. 因此,当您尝试使用它时,您正在访问一些您不拥有的随机存储器。 The operating system denies this.
操作系统否认这一点。 I am just surprised that the call to
GetWindowRect
doesn't cause the crash. 我只是惊讶地发现对
GetWindowRect
的调用不会导致崩溃。
On the other hand, your updated version declares RECT Rect
, which allocates memory on the stack. 另一方面,更新后的版本声明
RECT Rect
,它在堆栈上分配内存。 That memory is automatically allocated when your function is called, and is cleaned up when your function finishes. 该内存在调用函数时自动分配,并在函数完成时清除。
To clarify, this problem doesn't have to do with differences between pointer and reference. 需要澄清的是,此问题与指针和引用之间的差异无关。 The problem is exclusively due to memory allocation / ownership.
问题完全是由于内存分配/所有权。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.