我画了一个表格在表格的每个单元格填充了图片用于区别设备在线和报警情况。可是状态改变多次后图片突然消失。
procedure TfrmMain.PaintCanvas(iIndex : Integer;pic : TPicture);
var
  rect : TRect ;
  fontHeight : Integer;
  fontPoint : TPoint ;
  preBrush : TBrush ;
  preFont : TFont ;
  grp : TBitmap ;
  tmpImg : TImage ;
begin
  rect.Left := 0 ;
  rect.Top := 0 ;
  rect.Right := monitorList[iIndex].imgCtl.Width ;
  rect.Bottom := monitorList[iIndex].imgCtl.Height ;  tmpImg := TImage.Create(Self);
  tmpImg.Width := monitorList[iIndex].imgCtl.Width ;
  tmpImg.Height := monitorList[iIndex].imgCtl.Height ;
  //tmpImg.Picture.LoadFromFile(bmpFile);
  tmpImg.Picture.Assign(pic);  tmpImg.Canvas.Brush.Style := bsClear ;
  tmpImg.Canvas.Font.Size := 10 ;
  tmpImg.Canvas.Font.Style := [fsBold] ;
  if monitorList[iIndex].MouseIn then
    tmpImg.Canvas.Font.Color := clWhite
  else
    tmpImg.Canvas.Font.Color := clBlack ;
  fontHeight := tmpImg.Canvas.TextHeight(monitorList[iIndex].cMonitorName) ;  fontPoint.Y := (monitorList[iIndex].imgCtl.Height-fontHeight) div 2 ;
  fontPoint.X := 23 ;
  Canvas.Lock;
  tmpImg.Canvas.TextOut(fontPoint.X, fontPoint.Y, monitorList[iIndex].cMonitorName );  monitorList[iIndex].imgCtl.Canvas.CopyRect(monitorList[iIndex].imgCtl.ClientRect,tmpImg.Canvas,tmpImg.ClientRect);
  Canvas.Unlock;
  tmpImg.Free ;
end;我这个函数为什么图片会消失掉procedure TfrmMain.DrawImage(iIndex : Integer);
begin
  if monitorList[iIndex].MouseIn = TRUE then
  begin
    if monitorList[iIndex].state = ST_ONLINE then //在线
      //PaintCanvas(iIndex,'.\bmp\Green_2.bmp')
      PaintCanvas(iIndex,pic_Green_2)
    else if monitorList[iIndex].state = ST_OFFLINE then//不在线
      //PaintCanvas(iIndex,'.\bmp\Gray_2.bmp')
      PaintCanvas(iIndex,pic_Gray_2)
    else if monitorList[iIndex].state = ST_ALARM then//报警
      //PaintCanvas(iIndex,'.\bmp\Red_2.bmp') ;
      PaintCanvas(iIndex,pic_Red_2) ;
  end
  else
  begin
    if monitorList[iIndex].state = ST_ONLINE then //在线
      //PaintCanvas(iIndex,'.\bmp\Green_1.bmp')
      PaintCanvas(iIndex,pic_Green_1)
    else if monitorList[iIndex].state = ST_OFFLINE then//不在线
      //PaintCanvas(iIndex,'.\bmp\Gray_1.bmp')
      PaintCanvas(iIndex,pic_Gray_1)
    else if monitorList[iIndex].state = ST_ALARM then//报警
      PaintCanvas(iIndex,pic_Red_2) ;
     end;
end;procedure showAlarmThread.Execute;
var
  i : Integer;
begin
  while True do
  begin
    for i:=0 to frmMain.iCount*frmMain.bs-1 do
    begin
      if Not Terminated then
      begin
        if (frmMain.Monitorlist[i].state = ST_ALARM) And (frmMain.Monitorlist[i].MouseIn = FALSE) then
          frmMain.DrawImage(i);
      end
      else
        break;
    end;
    Sleep(500);
  end;
end;这个是报警时触发的线程

解决方案 »

  1.   

    在线程里执行操作form的函数?
    加上同步试一试
      

  2.   

    我已试过图片还是会消失。而且我把MouseIn方法去掉也会消失。在线程里直接调用PaintCanvas(iIndex : Integer;pic : TPicture); 函数也会消失
      

  3.   

    procedure TfrmMain.PaintCanvas(iIndex : Integer;pic : TPicture);
    var
      rect : TRect ;
      fontHeight : Integer;
      fontPoint : TPoint ;
      preBrush : TBrush ;
      preFont : TFont ;
      grp : TBitmap ;
      tmpImg : TImage ;
    begin
      tmpImg := TImage.Create(Self);
      try
        rect.Left := 0 ;
        rect.Top := 0 ;
        rect.Right := monitorList[iIndex].imgCtl.Width ;
        rect.Bottom := monitorList[iIndex].imgCtl.Height ;    tmpImg.Width := monitorList[iIndex].imgCtl.Width ;
        tmpImg.Height := monitorList[iIndex].imgCtl.Height ;
        //tmpImg.Picture.LoadFromFile(bmpFile);
        tmpImg.Picture.Assign(pic);    tmpImg.Canvas.Brush.Style := bsClear ;
        tmpImg.Canvas.Font.Size := 10 ;
        tmpImg.Canvas.Font.Style := [fsBold] ;
        if monitorList[iIndex].MouseIn then
          tmpImg.Canvas.Font.Color := clWhite
        else
          tmpImg.Canvas.Font.Color := clBlack ;
        fontHeight := tmpImg.Canvas.TextHeight(monitorList[iIndex].cMonitorName) ;    fontPoint.Y := (monitorList[iIndex].imgCtl.Height-fontHeight) div 2 ;
        fontPoint.X := 23 ;
        Canvas.Lock;
        try
          tmpImg.Canvas.TextOut(fontPoint.X, fontPoint.Y, monitorList[iIndex].cMonitorName );      monitorList[iIndex].imgCtl.Canvas.CopyRect(monitorList[iIndex].imgCtl.ClientRect,tmpImg.Canvas,tmpImg.ClientRect);
        finally
          Canvas.Unlock;
        end;
      finally
        tmpImg.Free ;
      end;
    end;具体没看出什么原因,加了些保护。
    还有就是操作主线程界面的东西的时候,我们一般使用同步的方法,而不是直接使用Execute方法来写。
    参考多线程编程同步部分!