Author |
Topic: DirectDraw - IDirectDraw.CreateSurface% (Read 1544 times) |
|
Michael Hutton
Developer
member is offline


Gender: 
Posts: 248
|
 |
DirectDraw - IDirectDraw.CreateSurface%
« Thread started on: Dec 28th, 2009, 08:27am » |
|
I know this is tedious but could some kind soul take a glance at the code below and see why I can't get IDirectDraw.CreateSurface% to work?
Code:
MODE 8
DDSCL_NORMAL = &8
DDSD_CAPS = 1
DDSCAPS_PRIMARYSURFACE = &200
SYS "GetSystemMetrics", 0 TO xscreen%
SYS "GetSystemMetrics", 1 TO yscreen%
SYS "LoadLibrary", "DDRAW.DLL" TO ddraw%
IF ddraw%=0 THEN ERROR 100, "Direct Draw not available"
SYS "GetProcAddress", ddraw%, "DirectDrawCreateEx" TO `DirectDrawCreateEx`
DIM IID_IDirectDraw7{a%, b%, c%, d%}
IID_IDirectDraw7.a% = &15E65EC0
IID_IDirectDraw7.b% = &11D23B9C
IID_IDirectDraw7.c% = &60002FB9
IID_IDirectDraw7.d% = &5BEA9797
DIM IDirectDraw{QueryInterface%, AddRef%, Release%, Compact%, CreateClipper%, \
\ CreatePalette%, CreateSurface%, DuplicateSurface%, \
\ EnumDisplayModes%, EnumSurfaces%, FlipToGDISurface%, \
\ GetCaps%, GetDisplayMode%, GetFourCCCodes%, GetGDISurface%, \
\ GetMonitorFrequency%, GetScanLine%, GetVerticalBlankStatus%, \
\ Initialize%, RestoreDisplayMode%, SetCooperativeLevel%, \
\ SetDisplayMode%, WaitForVerticalBlank%}
SYS `DirectDrawCreateEx`, 0, ^IDirectDraw%, IID_IDirectDraw7{}, 0
!(^IDirectDraw{}+4) = !IDirectDraw%
ON CLOSE PROC0 : QUIT
ON ERROR PROC0 : SYS "MessageBox", @hwnd%, REPORT$, 0, 48 : QUIT
REM Establish how DirectDraw will cooperate with GDI
SYS IDirectDraw.SetCooperativeLevel%, IDirectDraw%, 0, DDSCL_NORMAL TO R%
IF R% THEN ERROR 100,"Cannot set Cooperative Level "+STR$~R%
DIM DDPIXELFORMAT{dwSize%, \
\ dwFlags%, \
\ dwFourCC%, \
\ dwRGBBitCount%, \ Union!
\ dwRBitMask%, \ Union!
\ dwGBitMask%, \ Union!
\ dwBBitMask%, \ Union!
\ dwRGBAlphaBitMask% } :REM Union!
DIM DDCAPS{dwSize%, \
\ dwCKeyCaps%, \
\ dwPalCaps%, \
\ dwBltCaps%, \
\ dwAlphaCaps%, \
\ dwOverlayCaps%, \
\ dwVidMemTotal%, \
\ dwVidMemFree%, \
\ dwVidMemStride%, \
\ dwMaxVisibleOverlays%, \
\ dwCurrVisibleOverlays%, \
\ dwNumFourCCCodes%, \
\ dwAlignBoundarySrc%, \
\ dwAlignSizeSrc%, \
\ dwAlignBoundaryDest%, \
\ dwAlignSizeDest%, \
\ dwRops%, \ Possible error?
\ dwMinOverlayStretch%, \
\ dwMaxOverlayStretch%, \
\ dwMiscCaps% }
DIM ddsd{ dwSize%, \
\ dwFlags%, \
\ dwHeight%, \
\ dwWidth%, \
\ lPitch%, \
\ lXPitch%, \
\ dwBackBufferCount%, \
\ dwRefreshRate%, \
\ lpSurface%, \
\ ddckCKDestOverlay{l%,h%}, \
\ ddckCKDestBlt{l%,h%}, \
\ ddckCKSrcOverlay{l%,h%}, \
\ ddckCKSrcBlt{l%,h%}, \
\ pixelformat{} = DDPIXELFORMAT{}, \ possible error?
\ dwCaps%, \
\ dwSurfaceSize% }
ddsd.dwSize% = DIM(ddsd{})
ddsd.dwFlags% = DDSD_CAPS
ddsd.dwCaps% = DDSCAPS_PRIMARYSURFACE
SYS IDirectDraw.CreateSurface%, IDirectDraw%, ddsd{}, ^spSurface%, 0 TO R%
IF R% THEN ERROR 100,"Cannot CreateSurface "+STR$~R%
PROC0
END
DEF PROC0
SYS IDirectDraw.Release%, IDirectDraw%
SYS "FreeLibrary", ddraw%
ENDPROC
I think the problem is related to my definition of the structures, but was wondering if anyone already has these definitions somewhere?
I am trying to translate http://www.codeproject.com/KB/mobile/CeScreenGrabber.aspx "DirectDraw Screen Capture" - half way down the page.
Thank you,
Michael
|
|
Logged
|
|
|
|
admin
Administrator
member is offline


Posts: 1145
|
 |
Re: DirectDraw - IDirectDraw.CreateSurface%
« Reply #1 on: Dec 28th, 2009, 09:39am » |
|
Quote:I know this is tedious but could some kind soul take a glance at the code below and see why I can't get IDirectDraw.CreateSurface% to work? |
|
The prototype for IDirectDraw7::CreateSurface is:
Code:HRESULT CreateSurface(
LPDDSURFACEDESC2 lpDDSurfaceDesc,
LPDIRECTDRAWSURFACE7 FAR *lplpDDSurface,
IUnknown FAR *pUnkOuter
); Note in particular that the first parameter is a pointer to a DDSURFACEDESC2 structure. As far as I can see, you're passing a DDSURFACEDESC structure (Windows Mobile and Windows CE only) instead.
I assume you realise that the IDirectDraw interface is obsolete? It isn't supported in DirectX8 or later and is available only for backwards compatibility with DirectX7. Strictly speaking you shouldn't be using it in 'new' projects.
Richard.
|
|
Logged
|
|
|
|
Michael Hutton
Developer
member is offline


Gender: 
Posts: 248
|
 |
Re: DirectDraw - IDirectDraw.CreateSurface%
« Reply #2 on: Dec 29th, 2009, 01:24am » |
|
Quote:Note in particular that the first parameter is a pointer to a DDSURFACEDESC2 structure. As far as I can see, you're passing a DDSURFACEDESC structure (Windows Mobile and Windows CE only) instead. |
|
Well, that would explain a bit..doh. Quote:I assume you realise that the IDirectDraw interface is obsolete? It isn't supported in DirectX8 or later and is available only for backwards compatibility with DirectX7. Strictly speaking you shouldn't be using it in 'new' projects. |
|
Yes, I did realise but it was the only example I could find of capturing the Desktop. I was trying to get this to work and then was thinking of updating the code as and when I could. I am obviously intrested in speed... GetPixel is just way too slow..
I'll see where I get. Thanks for the reply.
Michael
|
|
Logged
|
|
|
|
Michael Hutton
Developer
member is offline


Gender: 
Posts: 248
|
 |
Re: DirectDraw - IDirectDraw.CreateSurface%
« Reply #3 on: Dec 29th, 2009, 02:30am » |
|
I seem to have got it working...
Code:
MODE 8
DDSCL_NORMAL = &8
DDSD_CAPS = 1
DDSCAPS_PRIMARYSURFACE = &200
SYS "GetSystemMetrics", 0 TO xscreen%
SYS "GetSystemMetrics", 1 TO yscreen%
SYS "LoadLibrary", "DDRAW.DLL" TO ddraw%
IF ddraw%=0 THEN ERROR 100, "Direct Draw not available"
SYS "GetProcAddress", ddraw%, "DirectDrawCreateEx" TO `DirectDrawCreateEx`
DIM IID_IDirectDraw7{a%, b%, c%, d%}
IID_IDirectDraw7.a% = &15E65EC0
IID_IDirectDraw7.b% = &11D23B9C
IID_IDirectDraw7.c% = &60002FB9
IID_IDirectDraw7.d% = &5BEA9797
DIM IDirectDraw{QueryInterface%, AddRef%, Release%, Compact%, CreateClipper%, \
\ CreatePalette%, CreateSurface%, DuplicateSurface%, \
\ EnumDisplayModes%, EnumSurfaces%, FlipToGDISurface%, \
\ GetCaps%, GetDisplayMode%, GetFourCCCodes%, GetGDISurface%, \
\ GetMonitorFrequency%, GetScanLine%, GetVerticalBlankStatus%, \
\ Initialize%, RestoreDisplayMode%, SetCooperativeLevel%, \
\ SetDisplayMode%, WaitForVerticalBlank%}
SYS `DirectDrawCreateEx`, 0, ^IDirectDraw%, IID_IDirectDraw7{}, 0
!(^IDirectDraw{}+4) = !IDirectDraw%
REM Apparently should give a pointer to the Primary Surface...
REM PRINT IDirectDraw%
REM PRINT !(IDirectDraw%+4)
REM PRINT !(!(IDirectDraw%+4)+44)
ON CLOSE PROC0 : QUIT
ON ERROR PROC0 : SYS "MessageBox", @hwnd%, REPORT$, 0, 48 : QUIT
REM Establish how DirectDraw will cooperate with GDI
SYS IDirectDraw.SetCooperativeLevel%, IDirectDraw%, 0, DDSCL_NORMAL TO R%
IF R% THEN ERROR 100,"Cannot set Cooperative Level "+STR$~R%
DIM DDPIXELFORMAT{dwSize%, \
\ dwFlags%, \
\ dwFourCC%, \
\ dwRGBBitCount%, \ Union!
\ dwRBitMask%, \ Union!
\ dwGBitMask%, \ Union!
\ dwBBitMask%, \ Union!
\ dwRGBAlphaBitMask% } :REM Union!
DIM DDSCAPS2{ \
\ dwCaps%, \
\ dwCaps2%, \
\ dwCaps3%, \
\ dwCaps4% }
DIM DDCAPS{dwSize%, \
\ dwCKeyCaps%, \
\ dwPalCaps%, \
\ dwBltCaps%, \
\ dwAlphaCaps%, \
\ dwOverlayCaps%, \
\ dwVidMemTotal%, \
\ dwVidMemFree%, \
\ dwVidMemStride%, \
\ dwMaxVisibleOverlays%, \
\ dwCurrVisibleOverlays%, \
\ dwNumFourCCCodes%, \
\ dwAlignBoundarySrc%, \
\ dwAlignSizeSrc%, \
\ dwAlignBoundaryDest%, \
\ dwAlignSizeDest%, \
\ dwRops%, \
\ dwMinOverlayStretch%, \
\ dwMaxOverlayStretch%, \
\ dwMiscCaps% }
DIM ddsd{ \
\ dwSize%, \
\ dwFlags%, \
\ dwHeight%, \
\ dwWidth%, \
\ dwPitchOrLinearSize%, \
\ dwBackBufferCount%, \
\ dwMipMapCount%, \
\ dwAlphaBitDepth%, \
\ dwReserved%, \
\ lpSurface%, \
\ ddckCKDestOverlay{l%,h%}, \
\ ddckCKDestBlt{l%,h%}, \
\ ddckCKSrcOverlay{l%,h%}, \
\ ddckCKSrcBlt{l%,h%}, \
\ ddpfPixelFormat{} = DDPIXELFORMAT{}, \
\ ddsCaps{} = DDSCAPS2{}, \
\ dwTextureStage% }
ddsd.dwSize% = DIM(ddsd{})
ddsd.dwFlags% = DDSD_CAPS
ddsd.ddsCaps.dwCaps% = DDSCAPS_PRIMARYSURFACE
SYS IDirectDraw.CreateSurface%, IDirectDraw%, ddsd{}, ^spSurface%, 0 TO R%
IF R% THEN ERROR 100,"Cannot CreateSurface "+STR$~R%
PROC0
END
DEF PROC0
SYS IDirectDraw.Release%, IDirectDraw%
SYS "FreeLibrary", ddraw%
ENDPROC
I'll keep people posted (if they are interested!)
|
|
Logged
|
|
|
|
admin
Administrator
member is offline


Posts: 1145
|
 |
Re: DirectDraw - IDirectDraw.CreateSurface%
« Reply #4 on: Dec 29th, 2009, 09:02am » |
|
Quote:Yes, I did realise but it was the only example I could find of capturing the Desktop.... GetPixel is just way too slow. |
|
What exactly are you trying to do? If you want to read pixels from the desktop quickly, why not simply BitBlt the entire desktop DC into a DIBSection? No need for anything complicated like DirectDraw or DirectX!
Richard.
|
|
Logged
|
|
|
|
Michael Hutton
Developer
member is offline


Gender: 
Posts: 248
|
 |
Re: DirectDraw - IDirectDraw.CreateSurface%
« Reply #5 on: Jan 2nd, 2010, 03:25am » |
|
Quote:What exactly are you trying to do? If you want to read pixels from the desktop quickly, why not simply BitBlt the entire desktop DC into a DIBSection? No need for anything complicated like DirectDraw or DirectX! |
|
My aim was to capture the desktop, modify it, and then BitBlt it back, many frames a second. I will do some 'speed tests' on BitBlt. I have been away for the new year. I suppose I was slightly enamoured by the potential of directly accessing the primary surface (monitor) through DDRAW. I realise it is depreciated.
Michael
|
|
Logged
|
|
|
|
admin
Administrator
member is offline


Posts: 1145
|
 |
Re: DirectDraw - IDirectDraw.CreateSurface%
« Reply #6 on: Jan 2nd, 2010, 09:46am » |
|
Quote:My aim was to capture the desktop, modify it, and then BitBlt it back, many frames a second. |
|
Write to the desktop DC? Can you even do that on Vista/Windows 7? I would have anticipated you would hit security restrictions in attempting that (unless running as an administrator) but I've not tried it.
Can't you achieve what you want by overlaying a transparent (layered) window on the desktop, and drawing to that? There have been several previous examples of doing that in BB4W.
Richard.
|
|
Logged
|
|
|
|
Michael Hutton
Developer
member is offline


Gender: 
Posts: 248
|
 |
Re: DirectDraw - IDirectDraw.CreateSurface%
« Reply #7 on: Jan 4th, 2010, 02:47am » |
|
Quote:Write to the desktop DC? Can you even do that on Vista/Windows 7? |
|
Code:
MODE 8
SYS "GetSystemMetrics", 0 TO xscreen%
SYS "GetSystemMetrics", 1 TO yscreen%
SYS "CreateDC", "DISPLAY", 0, 0, 0 TO hdcScreen%
SYS "CreateCompatibleDC", hdcScreen% TO hdcCompatible%
SYS "CreateCompatibleBitmap", hdcScreen%, xscreen%, yscreen% TO hbitmap%
SYS "SelectObject", hdcCompatible%, hbitmap% TO oldbm%
REPEAT
SYS "BitBlt", hdcCompatible%, 0, 0, xscreen%, yscreen%, hdcScreen%, 0, 0, &CC0020 TO R%
IF R% = 0 THEN ERROR 100, "Failed to BitBlt"
CIRCLE FILL RND(1280), RND(1024), RND(100)
SYS "BitBlt", hdcScreen%, 0,0, 640, 512, @memhdc%, 0, 0, &CC0020 TO R%
IF R% = 0 THEN ERROR 100, "Failed to BitBlt"
UNTIL FALSE
(Obviously - no cleanup code)
Works on my Vista Ultimate x64 edition. Which did rather surprise me, and you can draw to the desktop DC with SYS "LineTo" @desktopDC%, X%, Y%. So access seems pretty free. I am interested to see if DirectX/DDRAW provides a faster way of interacting with it.
Michael
|
|
Logged
|
|
|
|
Michael Hutton
Developer
member is offline


Gender: 
Posts: 248
|
 |
Re: DirectDraw - IDirectDraw.CreateSurface%
« Reply #8 on: Jul 28th, 2015, 7:41pm » |
|
Oh! ...and this also works with Windows 8 (v6).
Forgot about this.
Michael
|
|
Logged
|
|
|
|
|