EnumSurfaces

Started by
4 comments, last by jafe 16 years, 9 months ago
Hey, Has anybody had any experience getting IDirectDraw::EnumSurfaces to work properly? I'm not usually a directx coder so any help is appreciated. I have my code set up as so:


int index=0;

static HRESULT WINAPI DDEnum(
  LPDIRECTDRAWSURFACE7 lpDDSurface, 
  LPDDSURFACEDESC lpDDSurfaceDesc, 
  LPVOID lpContext)
{
	index++;
	lpDDSurface->Release();
	return DDENUMRET_OK;
}

...WinMain...


LPDIRECTDRAW7 lpDD=NULL;
HRESULT hr=DirectDrawCreateEx(NULL,(void**)&lpDD,IID_IDirectDraw7,NULL);

if(hr==DD_OK){
	hr=lpDD->EnumSurfaces(DDENUMSURFACES_DOESEXIST|DDENUMSURFACES_ALL ,NULL,NULL, (LPDDENUMSURFACESCALLBACK7)DDEnum);
	if(hr!=DD_OK){
		sndPlaySound("Windows XP Information Bar.wav",SND_SYNC);
	}
	lpDD->Release();
}
But the output remains as

index=0
DirectDrawCreateEx==DD_OK
lpDD->EnumSurfaces==DD_OK
And I was expecting for index to be at least 1 or more. Perhaps I am using the function wrongly, I am trying to use it to enumerate all of the active DirectX surfaces.
Advertisement
A couple of things:

Firstly, NEVER cast function pointers like that. It's an ideal way to get weird crashes. If the function pointer won't work without the cast, something is wrong with the function prototype and it needs fixed. Casting it just forces the compile error to turn into runtime error.

Secondly, Why would EnumSurfaces() give you a surface if you haven't created any yet? Creating a DirectDraw interface won't magically create any surfaces. Try creating a surface and then calling EnumSurfaces() and see if that makes any difference.

EDIT: Thirdly, I'm not at all sure you should be Release()ing the surface passed to your callback function. The docs don't seem to mention either way, but when your callback starts getting called, I'd check this out.
Quote:Original post by Evil Steve
A couple of things:

Firstly, NEVER cast function pointers like that. It's an ideal way to get weird crashes. If the function pointer won't work without the cast, something is wrong with the function prototype and it needs fixed. Casting it just forces the compile error to turn into runtime error.

Secondly, Why would EnumSurfaces() give you a surface if you haven't created any yet? Creating a DirectDraw interface won't magically create any surfaces. Try creating a surface and then calling EnumSurfaces() and see if that makes any difference.

EDIT: Thirdly, I'm not at all sure you should be Release()ing the surface passed to your callback function. The docs don't seem to mention either way, but when your callback starts getting called, I'd check this out.


Firstly, since it's pseudocode above, ASSUME I'm smart enough to right procedures to stop this.

Secondly, the SDK mentions that EnumSurfaces returns pointers to all drawable directdraw surfaces.

Thirdly, releasing a COM object used to be standard procedure after it's been intialised to clean up memory when the object is no longer needed.

EDIT: Also, it's not the one surface I want from my process, I'm trying to enumerate all of the directdraw surfaces in use and active on the computer at that time.
Quote:Original post by jafe
EDIT: Also, it's not the one surface I want from my process, I'm trying to enumerate all of the directdraw surfaces in use and active on the computer at that time.


Trying to grab the surfaces created by another application is IMPOSSIBLE (short of hacking apart windows/directx).

If you wanted to grab surfaces from another program you'd have to write a DLL hook that will take note of all surfaces created/destroyed, as well as display/store them somehow, though this can cause major problems with your PC if you don't know what you're doing, so just be careful.
Quote:Original post by jafe
Firstly, since it's pseudocode above, ASSUME I'm smart enough to right procedures to stop this.

Secondly, the SDK mentions that EnumSurfaces returns pointers to all drawable directdraw surfaces.

Thirdly, releasing a COM object used to be standard procedure after it's been intialised to clean up memory when the object is no longer needed.

EDIT: Also, it's not the one surface I want from my process, I'm trying to enumerate all of the directdraw surfaces in use and active on the computer at that time.

1) write [smile] And if it's psuedocode, that's even less reason to have the cast in there. You'd be surprised how many people just stuff a cast in there for the hell of it.

2) Where exactly does it say that? Exactly what it does depends on the flags you pass it. You're asking it for all the surfaces that already exist, and you haven't create any surfaces yet. So there's none to return, so the callback is never called, so this is correct behaviour. If you have created some surfaces, please show us the code you use to create them.

3) Yes, but you don't initialise the surface, do you? Like I said, I'm not sure what you're supposed to do here, the SDK docs don't actually say. What I mean is that when this starts working, you should check that you're not leaking memory or using invalid memory by incorrectly Release()ing or not Release()ing the suface.
EDIT: Never mind, it does say that - I just missed it.
Quote:Original post by Hollowtip
Quote:Original post by jafe
EDIT: Also, it's not the one surface I want from my process, I'm trying to enumerate all of the directdraw surfaces in use and active on the computer at that time.


Trying to grab the surfaces created by another application is IMPOSSIBLE (short of hacking apart windows/directx).

If you wanted to grab surfaces from another program you'd have to write a DLL hook that will take note of all surfaces created/destroyed, as well as display/store them somehow, though this can cause major problems with your PC if you don't know what you're doing, so just be careful.



Hacking the other process and getting the surface for it would be no problem - have fair experience in doing so, but I didn't want to use that method on this problem so I came accross that function EnumSurfaces which I hoped would indeed grab the surfaces in use by other processes. Guessing not.


Quote:Original post by Evil Steve
Quote:Original post by jafe
Firstly, since it's pseudocode above, ASSUME I'm smart enough to right procedures to stop this.

Secondly, the SDK mentions that EnumSurfaces returns pointers to all drawable directdraw surfaces.

Thirdly, releasing a COM object used to be standard procedure after it's been intialised to clean up memory when the object is no longer needed.

EDIT: Also, it's not the one surface I want from my process, I'm trying to enumerate all of the directdraw surfaces in use and active on the computer at that time.

1) write [smile] And if it's psuedocode, that's even less reason to have the cast in there. You'd be surprised how many people just stuff a cast in there for the hell of it.

2) Where exactly does it say that? Exactly what it does depends on the flags you pass it. You're asking it for all the surfaces that already exist, and you haven't create any surfaces yet. So there's none to return, so the callback is never called, so this is correct behaviour. If you have created some surfaces, please show us the code you use to create them.

3) Yes, but you don't initialise the surface, do you? Like I said, I'm not sure what you're supposed to do here, the SDK docs don't actually say. What I mean is that when this starts working, you should check that you're not leaking memory or using invalid memory by incorrectly Release()ing or not Release()ing the suface.
EDIT: Never mind, it does say that - I just missed it.


1) Yeh, I know my fair share of people who are guilty to this :)

2) As above, wasen't trying to get surfaces my process had made, but surfaces from other processes.

This topic is closed to new replies.

Advertisement