【问题标题】:How to free HRGN after CreatePolygonRgn?CreatePolygonRgn 后如何释放 HRGN?
【发布时间】:2021-09-03 07:46:28
【问题描述】:

我在下面完整编写了一个非常简单的方法,它在TForm 上的所有组件周围创建了一个多边形。由于 Delphi XE6 的编译器指出没有 HRGN.Free 方法,我只是问我是否应该 Free,嗯,任何东西在里面,我以前从未使用过HRGN 类型并且想确定。谢谢。

PS:我只是代表正确释放内存,如果这里甚至需要,仅此而已。


procedure TFormZoom.SetVisibleFormRegion;

var
    VisibleRegionPoints: array[0..11] of TPoint;
    VisibleFormRegion: HRGN;

begin
    try
        // XY points around all components that we want to be visible on the FormZoom
        VisibleRegionPoints[0] := Point(0, 0);
        VisibleRegionPoints[1] := Point(ZoomBoxPanel.Left + ZoomBoxPanel.Width, 0);
        VisibleRegionPoints[2] := Point(ZoomBoxPanel.Left + ZoomBoxPanel.Width, ZoomBoxPanel.Height);
        VisibleRegionPoints[3] := Point(ZoomBoxPanel.Left, ZoomBoxPanel.Height);
        VisibleRegionPoints[4] := Point(ZoomBoxPanel.Left, 0);
        VisibleRegionPoints[5] := Point(ColorBoxPanel.Width, 0);
        VisibleRegionPoints[6] := Point(ColorBoxPanel.Width, InfoValuesPanel.Top + InfoValuesPanel.Height);
        VisibleRegionPoints[7] := Point(0, InfoValuesPanel.Top + InfoValuesPanel.Height);
        VisibleRegionPoints[8] := Point(0, InfoValuesPanel.Top);
        VisibleRegionPoints[9] := Point(InfoValuesPanel.Width, InfoValuesPanel.Top);
        VisibleRegionPoints[10] := Point(ColorBoxPanel.Width, ColorBoxPanel.Height);
        VisibleRegionPoints[11] := Point(0, ColorBoxPanel.Height);
        try
            // we create a polygon region from the above points
            VisibleFormRegion := CreatePolygonRgn(VisibleRegionPoints, Length(VisibleRegionPoints), ALTERNATE);
            // finally, we set the FormZoom window region to the created polygon
            SetWindowRgn(Self.Handle, VisibleFormRegion, True);
        finally
            VisibleFormRegion.Free;  // <-- There is no method called Free!
        end;
    except
        on E: Exception do
        begin
            // in case of error, we log the exception only
            FormMain.ErrorLog.Add('TFormZoom.SetVisibleFormRegion: ' + E.ClassName + ' - ' + E.Message);
        end;
    end;
end;

【问题讨论】:

    标签: delphi winapi memory-management


    【解决方案1】:

    CreatePolygonRgn() 的文档中所述,必须使用DeleteObject() 释放返回的句柄:

    当您不再需要 HRGN 对象时,调用 DeleteObject 删除它的函数。

    更新

    正如Remy 指出的那样:在您的情况下,您正在调用SetWindowRgn(),这会将区域的所有权转移给系统。这意味着你不需要释放它。

    【讨论】:

    • 除了,将区域传递给SetWindowRgn()后不要删除,根据其documentation:“成功调用SetWindowRgn后,系统拥有由区域句柄hRgn。系统不会复制该区域。因此,您不应使用此区域句柄进行任何进一步的函数调用。尤其不要删除此区域句柄。系统在不再需要时删除区域句柄。"
    • @RemyLebeau 好点。我已经更新了答案。
    • "这意味着你不需要释放它"——除非SetWindowRgn()失败,也就是说。这是罕见的,但应该处理,以防万一
    • @RemyLebeau 我已经进行了调整,应该检查这些 WinApi 函数是否返回有效值,并采取相应措施。再次感谢您!
    猜你喜欢
    • 2016-10-26
    • 2012-09-13
    • 2012-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-13
    • 2019-07-09
    • 1970-01-01
    相关资源
    最近更新 更多