我正在将正在工作的 Borland C++ Builder 代码转换为 C# - 有趣,但并不总是那么容易......
void listCodecs(int Width, int Height)
{
int iSelected = 0;
ICINFO ci;
BITMAPINFOHEADER bih;
AnsiString asDesc;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biWidth = Width;
bih.biHeight = Height;
bih.biPlanes = 1;
bih.biBitCount = 24;
bih.biCompression = BI_RGB;
bih.biSizeImage = 0;
bih.biXPelsPerMeter = 1024;
bih.biYPelsPerMeter = 1024;
bih.biClrUsed = 0;
bih.biClrImportant = 0;
for (int c = 0, i = 0; ICInfo(ICTYPE_VIDEO, i, &ci); i++)
{
// Query the compressor for information.
HIC hic = ICOpen(ci.fccType, ci.fccHandler, ICMODE_QUERY);
if (hic)
{
if (ICERR_OK == ICCompressQuery( hic, &bih, NULL))
{
ICGetInfo( hic, &ci, sizeof(ICINFO));
asDesc = ci.szDescription;
// ComboBoxCODEC->Items->Add(as);
}
c++;
ICClose(hic);
}
}
}
我试图转换成这个稍微简化的代码:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public class ICINFO
{
public int dwSize;
public int fccType;
public int fccHandler;
public int dwFlags;
public int dwVersion;
public int dwVersionICM;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string szName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string szDescription;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string szDriver;
}
public class FOURCC
{
public static readonly int DIVX = FOURCC.mmioFOURCC('d', 'i', 'v', 'x');
public static readonly int MP42 = FOURCC.mmioFOURCC('M', 'P', '4', '2');
public static readonly int streamtypeVIDEO = mmioFOURCC('v', 'i', 'd', 's');
public static readonly int streamtypeAUDIO = mmioFOURCC('a', 'u', 'd', 's');
public static readonly int streamtypeMIDI = mmioFOURCC('m', 'i', 'd', 's');
public static readonly int streamtypeTEXT = mmioFOURCC('t', 'x', 't', 's');
public static readonly int ICTYPE_VIDEO = mmioFOURCC('v', 'i', 'd', 'c');
public static readonly int ICTYPE_AUDIO = mmioFOURCC('a', 'u', 'd', 'c');
public static readonly int ICM_FRAMERATE = mmioFOURCC('F', 'r', 'm', 'R');
public static readonly int ICM_KEYFRAMERATE = mmioFOURCC('K', 'e', 'y', 'R');
public static Int32 mmioFOURCC(char ch0, char ch1, char ch2, char ch3)
{
return ((Int32)(byte)(ch0) | ((byte)(ch1) << 8) |
((byte)(ch2) << 16) | ((byte)(ch3) << 24));
}
}
int ChangeCODEC()
{
int cntCodec = 0;
ICINFO ci = new ICINFO();
for (int i = 0; ICBase.ICInfo(FOURCC.ICTYPE_VIDEO, i, ci); i++)
{
cntCodec++;
}
return cntCodec;
}
我的问题是 ICInfo 没有在 ci 中返回任何合理的值 - 但由于循环运行了 13 次,这是我安装的编解码器的数量,所以有些东西正在工作。
更新:
对困惑感到抱歉。我稍微重新提出了我的问题 - 下面是不工作的麻烦制造者代码。我希望创建一个vido编解码器信息列表,但该列表具有预期的项目数量,但项目数据与我预期的不同。
这是来自一键式 C# 2008 测试应用程序的代码。
非常感谢您对此进行调查!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace vfwApp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
VideoCodecs myVideoCodecs = new VideoCodecs();
List<VideoCodecs.ExtractedVideoCodecInformation> levci = myVideoCodecs.showThem();
}
}
public class VideoCodecs
{
public static unsafe class ICBase
{
[DllImport("MSVFW32.dll", CharSet = CharSet.Ansi)]
public static extern bool ICInfo(
int fccType,
int fccHandler,
ICINFO lpicinfo
);
[DllImport("MSVFW32.dll"), PreserveSig]
public static extern int ICOpen(int fccType, int fccHandler, ICMODE wMode);
[DllImport("MSVFW32.dll")]
public static extern int ICClose(int hic);
[DllImport("MSVFW32.dll", CharSet = CharSet.Ansi)]
public static extern int ICGetInfo(
int hic,
ICINFO lpicinfo,
int cb
);
}
public class FOURCC
{
public static readonly int ICTYPE_VIDEO = mmioFOURCC('v', 'i', 'd', 'c');
public static readonly int ICTYPE_AUDIO = mmioFOURCC('a', 'u', 'd', 'c');
public static Int32 mmioFOURCC(char ch0, char ch1, char ch2, char ch3)
{
return ((Int32)(byte)(ch0) | ((byte)(ch1) << 8) | ((byte)(ch2) << 16) | ((byte)(ch3) << 24));
}
}
public enum ICMODE
{
ICMODE_COMPRESS = 1,
ICMODE_DECOMPRESS = 2,
ICMODE_FASTDECOMPRESS = 3,
ICMODE_QUERY = 4,
ICMODE_FASTCOMPRESS = 5,
ICMODE_DRAW = 8
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public class ICINFO
{
public int dwSize;
public int fccType;
public int fccHandler;
public int dwFlags;
public int dwVersion;
public int dwVersionICM;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string szName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string szDescription;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string szDriver;
}
public struct ExtractedVideoCodecInformation {
public int fccType;
public int fccHandler;
public int dwVersion;
public string name;
public string description;
public string driver;
}
public List<ExtractedVideoCodecInformation> showThem()
{
int cntCodec = 0;
ICINFO ci = new ICINFO();
ExtractedVideoCodecInformation evci = new ExtractedVideoCodecInformation();
List<ExtractedVideoCodecInformation> levci = new List<ExtractedVideoCodecInformation>();
for (int i = 0; ICBase.ICInfo(FOURCC.ICTYPE_VIDEO, i, ci); i++)
{
int hic = ICBase.ICOpen(ci.fccType, ci.fccHandler, ICMODE.ICMODE_QUERY);
if (hic != 0)
{
ICBase.ICGetInfo(hic, ci, 0);
// None of these fields are valid/sane now >>>
evci.fccType = ci.fccType;
evci.fccHandler = ci.fccHandler;
evci.dwVersion = ci.dwVersion;
evci.name = ci.szName;
evci.description = ci.szDescription;
evci.driver = ci.szDriver;
levci.Add(evci);
// <<< None of these fields are valid/sane now
ICBase.ICClose(hic);
}
cntCodec++;
}
return levci;
}
}
}