netying 2024-02-13 11:56 采纳率: 0%
浏览 8

关于TCanvas的Handle的奇怪问题

关于TCanvas的Handle的奇怪问题
C++ Builder 6.0

void __fastcall TForm1::Button1Click(TObject *Sender)
{

    for(int i=0;i<100;i++)
    {
        Graphics::TBitmap *bitmap=new  Graphics::TBitmap();
        bitmap->PixelFormat=pf24bit;
        bitmap->Width=256;
        bitmap->Height=256;
        HDC h=bitmap->Canvas->Handle;

        Memo1->Lines->Add("");//如果注释掉此句,则显示结果为OK,否则为HandleAllocated error

        if(bitmap->Canvas->HandleAllocated())
        {
                         Memo1->Lines->Add("OK:"+String(i));
        }
        else
        {
            Memo1->Lines->Add("HandleAllocated error: "+String(i));
        }
        delete bitmap;
    }
}

在上述代码中,运行结果为HandleAllocated error;如果注释掉则显示结果为OK,百思不得其解。

  • 写回答

4条回答 默认 最新

  • 专家-郭老师 Java领域新星创作者 2024-02-13 11:57
    关注

    参考通义千问和郭老师的小迷弟雅思莫了-编写提供,主要是为了帮助您快速解决问题,如下回答,您可以参考下,如有问题,评论区留言。

    您在代码中遇到的问题与TCanvas的Handle和内存管理有关。在C++ Builder 6.0环境下,当您创建一个TBitmap对象时,其Canvas属性会自动关联一个HDC(设备上下文句柄)。然而,由于TCanvas的Handle属性访问的是一个底层Windows GDI资源,它依赖于TBitmap对象的存在。

    在您的循环中,每迭代一次,都会创建一个新的TBitmap对象并获取其Canvas的Handle,然后立即将其删除。但是,由于Windows GDI资源的释放时机可能滞后于TBitmap对象的析构,所以在删除TBitmap后立即检查Canvas的Handle有效性时,可能会导致HandleAllocated()函数返回错误结果。

    当您在删除TBitmap之前调用Memo1->Lines->Add("")时,由于字符串操作和界面更新引入了额外的延迟,这恰好为GDI资源的释放提供了一些时间,所以此时检查Handle的有效性更有可能得到正确的结果(即"OK")。

    为了解决这个问题,并确保正确释放资源,建议在不再使用TBitmap及其Canvas之后,显式地调用ReleaseHandle()方法来释放关联的GDI资源,然后再删除TBitmap对象:

    void __fastcall TForm1::Button1Click(TObject *Sender) {
        for(int i = 0; i < 100; i++) {
            Graphics::TBitmap *bitmap = new Graphics::TBitmap();
            bitmap->PixelFormat = pf24bit;
            bitmap->Width = 256;
            bitmap->Height = 256;
            HDC h = bitmap->Canvas->Handle;
    
            // ... 进行您需要的绘图操作 ...
    
            bitmap->Canvas->ReleaseHandle(); // 显式释放关联的GDI资源
            delete bitmap;
    
            // 在这里检查Handle的有效性
            if (/*...*/) {
                Memo1->Lines->Add("...");
            } else {
                Memo1->Lines->Add("...");
            }
        }
    }
    

    请注意,上述代码仅解决了问题的现象,但在实际应用中,请确保根据您的实际需求合理安排绘图、资源释放和对象销毁逻辑。

    评论

报告相同问题?

问题事件

  • 创建了问题 2月13日

悬赏问题

  • ¥20 测距传感器数据手册i2c
  • ¥15 RPA正常跑,cmd输入cookies跑不出来
  • ¥15 求帮我调试一下freefem代码
  • ¥15 matlab代码解决,怎么运行
  • ¥15 R语言Rstudio突然无法启动
  • ¥15 关于#matlab#的问题:提取2个图像的变量作为另外一个图像像元的移动量,计算新的位置创建新的图像并提取第二个图像的变量到新的图像
  • ¥15 改算法,照着压缩包里边,参考其他代码封装的格式 写到main函数里
  • ¥15 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法