你提到希望的 “序列号” 和 “类型”。没有“类型”,但有制造商ID和产品ID。大多数情况下,这些信息不会作为有意义的字符串存储在您返回的信息中......它们只是数字值。他们都在前16个字节。
我会根据您引用的规范解码开始。
字节0,1,2,3,4,5,6,7 - 报头信息
这应该是文本字符串 “00H FFH FFH FFH FFH FFH FFH 00H”,这作为我们正在查看有效EDID块的完整性检查。您的数据正是我们所期望开始了:
00 FF FF FF FF FF FF 00
字节8和9 - 制造商ID。
这些标识由Microsoft分配,且为三字母代码。哦,当然,他们可能已经浪费了三个ASCII字符的整个字节。但这太明智了。所以他们在头文件上写了一个非常“非魔术”数字的8个字节,并发明了一种“巧妙”的方法将这三个字母编码为由两个字节保存的16位。他们怎么把它关掉?
+--------+--------+
| Byte 8 | Byte 9 |
--------+--------+--------+
Bit #
-----------------=---------
Meaning 0αααααββ βββγγγγγ
所以字节8的最高位总是零,并且剩余的15位被分成三个组,每组5个比特(我已经称为α,β和γ)的。每个被解释为一个字母,其中“00001 = A”; “00010 = B”; ...“11010 = Z”。
你已经有了:
10 AC
和十六进制10AC
表示为16个二进制位是0001000010101100
。因此,让我们把该表再次:
+--------+--------+
| Byte 8 | Byte 9 |
--------+--------+--------+
Bit #
-----------------=---------
Meaning 0αααααββ βββγγγγγ
-----------------=---------
Yours 00010000 10101100
所以α = 00100
(十进制4),β = 00101
(十进制5),γ = 01100
(十进制12)。用这些十进制数字作为英文字母的索引,我们得到D-E-L。通过这个神秘的魔法,我们确定您的显示器最有可能由戴尔制造。 :)
字节10和11 - 产品ID代码
这是一个两字节数,由制造商分配,存储为 “LSB第一”。这就是说第一个字节是最不重要的地方值。你有:
4C 40
我们需要解释为十六进制数字404C
。
字节12,13,14,15 - 序列号。
这是制造商指定的32位值,它不需要格式。它“通常先存储为LSB”,但不一定是。
53 43 34 42
可以理解,作为0x53433442
,或0x42344353
,或任何...只要你在比较反对另一个价值是一致的。
所以,现在你看到它只是三个字母和一些数字。一旦将字节存入缓冲区,有很多方法可以提取信息。 @freerider提供了一些关于这方面的信息,我会再多加一些。
EDID标准说,你回来的描述是128字节。这里的注册表项就是这种情况,你可以假设如果没有128个字节,它就会损坏。因此,使用@freerider提供的代码,就不需要传入比这更大的任何东西......如果这是您感兴趣的EDID的唯一部分,技术上可以降低到16:
#define EDID_BUFFER_SIZE 128
// in idiomatic C++ it's better to say:
// const size_t edidBufferSize = 128;
BYTE edidBuffer[EDID_BUFFER_SIZE];
DWORD nLength = GetLocalMachineProfileBuffer(Buffer, EDID_BUFFER_SIZE);
if (nLength != EDID_BUFFER_SIZE) {
// handle error case, not a valid EDID block
} else {
// valid EDID block, do extraction:
// * manufacturer ID
// * product ID
// * serial number
}
(注:我宁愿避免像上面@ freerider的sizeof(Buffer)
阵列使用sizeof
虽然在技术上会在这种情况下工作,它不返回元素的数量阵列中......而the number of bytes the array occupies in memory。在这种情况下,元素碰巧实际上是字节,所以它会工作......但是你很快遇到问题,比如当你通过指针传递一个数组到另一个函数,突然它开始报告它的大小作为指针的大小。 ..)
除此之外,你如何从字节缓冲区中提取结构数据的问题是一个非常普遍的问题,并且是C风格编程的基础,如果你不知道从哪里开始那么你应该通过更简单的程序工作。从制造商名称中取出三个五位段涉及诸如位移,位掩码或位域之类的事情。通过数组处理地址以及如何索引数组和类似的东西。
最接近平行的问题,我能找到的副手,现在是这样的:
extract IP from a buffer of bytes
很多方法可以做到这一点,但一个有趣的是,你可以在内存中定义一个结构的布局和然后告诉程序“嘿,我发现的这块内存就像我定义的结构一样布置,所以让我从中提取信息就好像我在程序中定义对象一样......”
但是,你必须对数据结构对齐等问题敏感。这是因为你的编译器会自然地将对象放入内存不一定匹配方式你认为它会做:
http://en.wikipedia.org/wiki/Data_structure_alignment
看上面的信息至少应该能够让射击在阅读一些教程和看看有什么作用。如果你无法弄清楚问题的一部分,那么就把这一小部分当作自己的问题来解决,并且展示你所尝试的以及为什么它不起作用......
相关:http://stackoverflow.com/questions/4831471/windows-get-number-of-monitors-including-disabled-ones – HostileFork