簡體   English   中英

為什么用指針調用GetWindowRect會導致異常,但地址卻沒有

[英]Why does calling GetWindowRect with pointer cause exception but address doesn't

我在dll中有一個實用程序功能,可將窗體放在主機應用程序屏幕上。 我正在使用RAD Studio XE2。 我必須手動執行此操作,因為主機應用程序是非VCL並且TForm的表單放置參數無法正常工作。 下面的代碼有效。 這兩個函數都聲明為靜態,並且我之前已將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;
         }
      }
   }

我最初的GetAppCenter代碼使用Rect *代替並返回正確的值,但是當我設置f-> Left時拋出了訪問沖突異常。 誰能解釋為什么?

   // 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 

這是不正確的。 GetWindowRect需要一個有效的RECT*參數,以便它填充此指針指向的內存。 相反,您傳遞的是未初始化的指針,期望有某種魔術使之有效。 相反,您遇到訪問沖突。 你需要:

  RECT Rect;
  GetWindowRect(Application->Handle, &Rect); // <<--- Note &
  //Rect.left 

GetWindowRect期望調用方擁有矩形結構。

在您的原始版本中,您的*Rect不會指向任何有效的內存。 因此,當您嘗試使用它時,您正在訪問一些您不擁有的隨機存儲器。 操作系統否認這一點。 我只是驚訝地發現對GetWindowRect的調用不會導致崩潰。

另一方面,更新后的版本聲明RECT Rect ,它在堆棧上分配內存。 該內存在調用函數時自動分配,並在函數完成時清除。

需要澄清的是,此問題與指針和引用之間的差異無關。 問題完全是由於內存分配/所有權。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM