Microsoft DirectX 8.0 (C++) |
Objects stored as resources or at some other location in memory are loaded in much the same way as file objects. See Loading an Object from a File.
With memory objects, however, the wszName, guidObject, and wszFileName members of the DMUS_OBJECTDESC structure are irrelevant. Instead, you must obtain a pointer to the block of memory occupied by the object, and its size, and put these in the pbMemData and llMemLength members respectively. You must also set the DMUS_OBJ_MEMORY flag in the dwFlags member.
The memory cannot be released once IDirectMusicLoader8::GetObject has been called, because the loader keeps an internal pointer to the memory to facilitate caching data. If you want to clear it out, call IDirectMusicLoader8::SetObject with the same DMUS_OBJECTDESC descriptor, but with NULL in pbMemData. This is not an issue when loading from a resource, because resource memory is not freed.
The following function loads a MIDI file from a resource into a segment:
// m_pLoader is a valid IDirectMusicLoader8 pointer. IDirectMusicSegment8* m_pSegment; HRESULT LoadMidi(HMODULE hMod, WORD ResourceID) { HRESULT hr; DMUS_OBJECTDESC ObjDesc; HRSRC hFound = FindResource(hMod, MAKEINTRESOURCE(ResourceID), RT_RCDATA); HGLOBAL hRes = LoadResource(hMod, hFound); ObjDesc.dwSize = sizeof(DMUS_OBJECTDESC); ObjDesc.guidClass = CLSID_DirectMusicSegment; ObjDesc.dwValidData = DMUS_OBJ_CLASS | DMUS_OBJ_MEMORY; ObjDesc.pbMemData = (BYTE *) LockResource(hRes); ObjDesc.llMemLength = SizeofResource(hMod, hFound); hr = m_pLoader->GetObject( &ObjDesc, IID_IDirectMusicSegment8, (void**) &m_pSegment ); return hr; }
Objects referenced by other objects must be loaded first. For example, if you load a segment that contains a reference to a style, the style must already be loaded in order for the segment to play correctly. Alternatively, you can call IDirectMusicLoader8::SetObject on the style so that the segment can find it.