我想将一个EMF/WMF图形调入Image中,然后旋转一定的角度显示。请各位兄弟援手。

解决方案 »

  1.   

    坐标变换,有一点难度。
    给你一个函数,自己根据需求修改吧!
    { Fast routine for EMF drawing }
    procedure DrawEMF(ACanvas:TCanvas; AEMF:TMetafile; ARect:TRect);
    var TempRect: TRect;  function EnumEMFRecordsProc(DC:HDC; HandleTable:PHandleTable;
        EMFRecord:PEnhMetaRecord; ObjectCount:Integer; OptionData:Pointer):BOOL; stdcall;
      begin
        Result := TRUE;
        case EMFRecord^.iType of
          EMR_ELLIPSE..EMR_PIE,
          EMR_BITBLT..EMR_STRETCHDIBITS,
          EMR_EXTTEXTOUTA,EMR_EXTTEXTOUTW:
          begin
            //TempRect := PEMRRectangle(EMFRecord)^.rclBox;
            //InflateRect(TempRect,1,1);
            //if RectVisible(DC,TempRect) then
              PlayEnhMetafileRecord(DC,HandleTable^,EMFRecord^,ObjectCount);
          end;
          else
            PlayEnhMetafileRecord(DC,HandleTable^,EMFRecord^,ObjectCount);
        end;
      end;begin
      Windows.EnumEnhMetafile(ACanvas.Handle,AEMF.Handle,@EnumEMFRecordsProc,Nil,ARect);
    end;
      

  2.   

    smhpnuaa(农奴翻身感谢党) ,什么意思呀?
      

  3.   

    根据 Borlandor(五角▲大民) 的指点,我写了以下这个例子,但不知怎样才能使图元正好显示在PaintBox1的中心,请高手指教procedure DrawEMF(ACanvas: TCanvas; AEMF: TMetafile; ARect: TRect; Angle: Double);
      function EnumEMFRecordsProc(DC: HDC; HandleTable: PHandleTable;
        EMFRecord: PEnhMetaRecord; ObjectCount:Integer; OptionData:Pointer): BOOL; stdcall;
      var
        TempRect: TRect;
      begin
        Result := true;
        case EMFRecord^.iType of
          EMR_ELLIPSE..EMR_PIE,
          EMR_BITBLT..EMR_STRETCHDIBITS,
          EMR_EXTTEXTOUTA, EMR_EXTTEXTOUTW:
          begin
            TempRect := PEMRRectangle(EMFRecord)^.rclBox;
            InflateRect(TempRect, 1, 1);
            if RectVisible(DC, TempRect) then
              PlayEnhMetafileRecord(DC, HandleTable^, EMFRecord^, ObjectCount);
          end;
          else
            PlayEnhMetafileRecord(DC, HandleTable^, EMFRecord^, ObjectCount);
        end;//case EMFRecord^.iType of
      end;  procedure Rotate(Angle: Double);
      const
        RadPerDeg = 0.01745329251994329;//PI / 180
      var
        p2: TXForm;
        Sine, CoSine: Single;
        tmpRadian: Single;
        tmpWidth, tmpHeight: Integer;
        x1, x2, x3: Single;
        y1, y2, y3: Single;
        MinX, MinY: Single;
      begin
        ModifyWorldTransform(ACanvas.Handle, p2, MWT_IDENTITY);
        tmpRadian := Angle * RadPerDeg;
        Sine := Sin(tmpRadian);
        CoSine := Cos(tmpRadian);    tmpWidth := ARect.Right - ARect.Left;
        tmpHeight := ARect.Bottom - ARect.Top;
        x1 := (tmpHeight * Sine);
        y1 := (tmpHeight * CoSine);
        x2 := (tmpWidth * CoSine + tmpHeight * Sine);
        y2 := (tmpHeight * CoSine - tmpWidth * Sine);
        x3 := (tmpWidth * CoSine);
        y3 := (-tmpWidth * Sine);    MinX := Min(0, Min(x1, Min(x2, x3)));
        MinY := Min(0, Min(y1, Min(y2, y3)));    p2.eM11 := CoSine;
        p2.eM12 := -Sine;
        p2.eM21 := Sine;
        p2.eM22 := CoSine;
        p2.eDx := -MinX;
        p2.eDy := -MinY;
        SetWorldTransform(ACanvas.Handle, p2);
      end;
    begin
      SetGraphicsMode(ACanvas.Handle, GM_ADVANCED);
      Rotate(Angle);
      EnumEnhMetafile(ACanvas.Handle, AEMF.Handle, @EnumEMFRecordsProc, nil, ARect);
      SetGraphicsMode(ACanvas.Handle, GM_COMPATIBLE);
    end;
    procedure TForm1.Button1Click(Sender: TObject);
    var
      aWmf: TMetaFile;
      tmpPath: array [0..255] of Char;
    begin
      GetModuleFileName(HInstance, tmpPath, 256);
      aWmf := TMetaFile.Create;
      aWmf.LoadFromFile(ExtractFilePath(tmpPath) + '\WMF\arrow.wmf');
      DrawEMF(PaintBox1.Canvas, aWmf, PaintBox1.ClientRect, 60);
    end;