I'm working with RIFFCHUNK
structures, declared (in the "foreign" modules) as (citing MMSystem
and DirectShow9
):
type FOURCC = DWORD; { a four character code }
type _riffchunk = record
fcc: FOURCC;
cb: DWORD;
end;
type RIFFCHUNK = _riffchunk;
My particular interest here is fcc
field, which type resolves to LongWord
. In the other hand, meaningful values for fcc
are strings comprised by 4 ASCII printable single-byte characters. I'd like to avoid the following ugliness (citing MMSystem
):
const FOURCC_RIFF = $46464952; { 'RIFF' }
... and use actual, self-explaining four character string literals for assignment and comparison.
What have I tried so far and got stuck shown below:
const idRIFF: packed array [1..4] of AnsiChar = 'RIFF';
var Chunk: RIFFCHUNK;
begin
Chunk.fcc := FOURCC(idRIFF); { works, but requires a typecast in implementation }
Since idRIFF
isn't true constant, it cannot be used in declaration of properly typed symbol.
So, I'd like to ask an advice where to go further in this beautification affair?
Please note what FOURCC
type is "foreign", so I cannot just redeclare it as character array.
This declaration will treat FOURCC_RIFF as a constant using a string literal:
const
FOURCC_RIFF_S : array[0..SizeOf(FOURCC)-1] of AnsiChar = 'RIFF';
var
FOURCC_RIFF : FOURCC absolute FOURCC_RIFF_S;
If writable constant directive is on, that could be fixed by catching the compiler directive as well.
{$IFOPT J+}
{$DEFINE UNDO_WRCONST}
{$J-}
{$ENDIF}
const
FOURCC_RIFF_S : array[0..SizeOf(FOURCC)-1] of AnsiChar = 'RIFF';
var
FOURCC_RIFF : FOURCC absolute FOURCC_RIFF_S;
{$IFDEF UNDO_WRCONST}
{$J+}
{$ENDIF}
No typecasting needed and compiler treats the value as a true constant.
var
Chunk: RIFFCHUNK;
...
Chunk.fcc := FOURCC_RIFF;
The multimedia API defines MAKEFOURCC()
and mmioFOURCC()
macros, both of which convert 4 characters into a FOURCC
value, eg:
Chunk.fcc := MAKEFOURCC('R', 'I', 'F', 'F');
Chunk.fcc := mmioMAKEFOURCC('R', 'I', 'F', 'F');
In case Delphi does not have an existing translation in the MMSystem
unit (it should, but I cannot check right now), here is one:
function MAKEFOURCC(ch0, ch1, ch2, ch3: AnsiChar): LongWord;
begin
Result := LongWord(Ord(ch0)) or (LongWord(Ord(ch1)) shl 8) or (LongWord(Ord(ch2)) shl 16) or (LongWord(Ord(ch3)) shl 24);
end;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With