简体   繁体   English

将VB代码转换为Delphi(它将从EMF文件中提取图像)

[英]Conversion of VB Code to Delphi (It will extract image from EMF File)

While searching in the net i got few lines of code in VB for extracting an image from EMF File. 在网上搜索时,我在VB中有几行代码用于从EMF文件中提取图像。

I tried to convert that into Delphi but doesnt work. 我试图将其转换为Delphi,但不起作用。

Help me in converting this code to delphi. 帮助我将这段代码转换为delphi。

Public Function CallBack_ENumMetafile(ByVal hdc As Long, _
                                      ByVal lpHtable As Long, _
                                      ByVal lpMFR As Long, _
                                      ByVal nObj As Long, _
                                      ByVal lpClientData As Long) As Long
  Dim PEnhEMR As EMR
  Dim PEnhStrecthDiBits As EMRSTRETCHDIBITS
  Dim tmpDc As Long
  Dim hBitmap  As Long
  Dim lRet As Long
  Dim BITMAPINFO As BITMAPINFO
  Dim pBitsMem As Long
  Dim pBitmapInfo As Long
  Static RecordCount As Long

  lRet = PlayEnhMetaFileRecord(hdc, ByVal lpHtable, ByVal lpMFR, ByVal nObj)


  RecordCount = RecordCount + 1
  CopyMemory PEnhEMR, ByVal lpMFR, Len(PEnhEMR)
  Select Case PEnhEMR.iType
  Case 1  'header
    RecordCount = 1
  Case EMR_STRETCHDIBITS
    CopyMemory PEnhStrecthDiBits, ByVal lpMFR, Len(PEnhStrecthDiBits)
    pBitmapInfo = lpMFR + PEnhStrecthDiBits.offBmiSrc
    CopyMemory BITMAPINFO, ByVal pBitmapInfo, Len(BITMAPINFO)
    pBitsMem = lpMFR + PEnhStrecthDiBits.offBitsSrc

    tmpDc = CreateDC("DISPLAY", vbNullString, vbNullString, ByVal 0&)
    hBitmap = CreateDIBitmap(tmpDc, _
                            BITMAPINFO.bmiHeader, _
                            CBM_INIT, _
                            ByVal pBitsMem, _
                            BITMAPINFO, _
                            DIB_RGB_COLORS)
    lRet = DeleteDC(tmpDc)

  End Select
  CallBack_ENumMetafile = True

End Function

What you've posted is an instance of an EnumMetaFileProc callback function, so we'll start with the signature: 您发布的是EnumMetaFileProc回调函数的实例,因此我们将从签名开始:

function Callback_EnumMetafile(
  hdc: HDC;
  lpHTable: PHandleTable;
  lpMFR: PMetaRecord;
  nObj: Integer;
  lpClientData: LParam
): Integer; stdcall;

It begins by declaring a bunch of variables, but I'll skip that for now since I don't know which ones we'll really need, and VB has a more limited type system than Delphi. 它从声明一堆变量开始,但是由于我不知道我们真正需要哪些变量,因此我现在将跳过该变量,并且VB的类型系统比Delphi更有限。 I'm going to declare them as we need them; 我将在需要它们时声明它们; you can move them all to the top of the function yourself. 您可以将它们全部移到函数顶部。

Next comes a call to PlayEnhMetaFileRecord using most of the same parameters that were passed into the callback function. 接下来是使用传递给回调函数的大多数相同参数来调用PlayEnhMetaFileRecord The function returns a Bool, but then the code ignores it, so let's not bother with lRet . 该函数返回一个Bool,但是随后代码将其忽略,因此我们不必理会lRet

PlayEnhMetaFileRecord(hdc, lpHtable, lpMFR, nObj);

Next we initialize RecordCount . 接下来,我们初始化RecordCount It's declared static, which means it retains its value from one call to the next. 它被声明为静态的,这意味着它保留了从一个调用到下一个调用的值。 That looks a little dubious; 看起来有点可疑; it should probably be passed in as a pointer in the lpClientData parameter, but let's not veer too far from the original code for now. 它可能应该作为指针传入lpClientData参数,但是现在我们不要偏离原始代码太远。 Delphi does static variables with typed constants , and they need to be modifiable, so we'll use the $J directive: Delphi使用类型常量来处理静态变量,并且它们需要可修改,因此我们将使用$ J指令:

{$J+}
const
  RecordCount: Integer = 0;
{$J}

Inc(RecordCount);

Next we mcopy some of the meta record into another variable: 接下来,我们将一些元记录复制到另一个变量中:

var
  PEnhEMR: TEMR;

CopyMemory(@PEnhEMR, lpMFR, SizeOf(PEnhEMR));

It looks a little strange to copy the TMetaRecord structure onto a TEMR structure since they aren't really similar, but again, I don't want to veer from the original code too much. 将TMetaRecord结构复制到TEMR结构看起来有点奇怪,因为它们实际上并不相似,但是再次,我不想过多地偏离原始代码。

Next is a case statement on the iType field. 接下来是iType字段上的case语句。 The first case is when it's 1: 第一种情况是1:

case PEnhEMR.iType of
  1: RecordCount := 1;

The next case is that it's emr_StretchDIBits. 下一种情况是它是emr_StretchDIBits。 It copies more of the meta record, and then assigns some other pointers to refer to subsections of the main data structure. 它复制更多的元记录,然后分配一些其他指针来引用主数据结构的子节。

var
  PEnhStretchDIBits: TEMRStretchDIBits;
  BitmapInfo: TBitmapInfo;
  pBitmapInfo: Pointer;
  pBitsMem: Pointer;

  emr_StretchDIBits: begin
    CopyMemory(@PEnhStrecthDIBits, lpMFR, SizeOf(PEnhStrecthDIBits));
    pBitmapInfo := Pointer(Cardinal(lpMFR) + PEnhStrecthDiBits.offBmiSrc);
    CopyMemory(@BitmapInfo, pBitmapInfo, SizeOf(BitmapInfo));
    pBitsMem := Pointer(Cardinal(lpMFR) + PEnhStrecthDiBits.offBitsSrc);

Then comes what seems to be the real meat of the function, where we create a display context and a bitmap to go with it using the DIBits extracted using the previous code. 然后似乎是该功能的实质,在这里我们使用上一代码提取的DIBits创建一个显示上下文和一个位图,将其与之配合使用。

var
  tmpDc: HDC;
  hBitmap: HBitmap;

    tmpDc := CreateDC('DISPLAY', nil, nil, nil);
    hBitmap := CreateDIBitmap(tmpDc, @BitmapInfo.bmiHeader, cbm_Init,
      pBitsMem, @BitmapInfo, dib_RGB_Colors);
    DeleteDC(tmpDc);
  end; // emr_StretchDIBits
end; // case

Finally, we assign a return value to the callback function: 最后,我们为回调函数分配一个返回值:

Result := 1;

So, there's your translation. 因此,有您的翻译。 Wrap it in a begin - end block, remove my commentary, and move all the variable declarations to the top, and you should have Delphi code that's equivalent to your VB code. 将其包装在begin - end块中,删除我的注释,然后将所有变量声明移到顶部,您应该拥有与VB代码等效的Delphi代码。 However, all this code ultimately does is generate memory leaks. 但是,所有这些代码最终所做的只是生成内存泄漏。 The hBitmap variable is local to the function, so the bitmap handle it holds is leaked as soon as this function returns. hBitmap变量是该函数的局部变量,因此该函数返回后,它所保存的位图句柄就会泄漏。 I assume the VB code works for you, though, so I guess you have some other plans for what to do with it. 不过,我认为VB代码适合您,因此我想您还有其他计划来使用它。

If you're working with metafiles, have you considered using the TMetafile class in the Graphics unit? 如果您正在使用图元文件,是否考虑过在Graphics单元中使用TMetafile类? It might make your life easier. 这可能会使您的生活更轻松。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM