Failed to GetDC for overlays surface
- From: Felipe Monteiro de Carvalho <felipe@xxxxxxxxx>
- Date: Sat, 23 Jun 2007 19:12:02 +0200
Hello,
I am trying to generate a overlays surface and then do some drawing to it. More specifically I want to draw some lines and also enlange a piece of the screen and draw to my overlay.
So far I suceeded in generating the overlays surface and drawing a black square using IDirectDrawSurface.Blt without a source surface.
Now I would like to get a DC to use drawing operations, or do anything else that allows me to draw lines and do other basic operations on my overlay, but IDirectDrawSurface.GetDC fails with 88760249 "Cannot create DC"
Does anyone know what factors cause IDirectDrawSurface.GetDC to fail? I read the reference on MSDN but there are no details about that.
Bellow is my full code. On the WM_PAINT event of the main window I draw a black square on the overlay. Bellow it is code to get a DC and draw a square using windows GDI instead, but that fails.
Thanks
program overlay;
{$ifdef fpc}
{$mode delphi}{$H+}
{$endif}
uses
Classes, SysUtils,
Windows, DirectDraw;
{ Global Variables }
var
{ DirectX variables }
g_lpdd: IDirectDraw7 = nil;
g_lpddsPrimary: IDirectDrawSurface7 = nil;
g_lpddsOverlay: IDirectDrawSurface7 = nil;
g_lpClipper: IDirectDrawClipper = nil;
{ Debug variables }
DebugLoc, DebugInfo: Cardinal;
ddrval: HRESULT;
{ prototypes }
function InitOverlays: Boolean; forward;
function WndProc(ahWnd: HWND; amessage: UINT; awParam: WPARAM; alParam: LPARAM): LResult; stdcall; forward;
procedure CreateMainWindow; forward;
procedure ShowError; forward;
{*******************************************************************
* InitOverlays ()
*
* Initializes DirectX and creates a overlay surface
*******************************************************************}
function InitOverlays: Boolean;
var
ddsd, ddsdOverlay: DDSURFACEDESC2;
capsDrv: TDDCaps;
pixelFormats: array[0..3] of DDPIXELFORMAT;
begin
Result := False;
DebugInfo := 0;
DebugLoc := 0;
{ Init DirectDraw }
ddrval := DirectDrawCreateEx(nil, g_lpdd, IID_IDirectDraw7, nil);
if ddrval <> DD_OK then
begin
DebugLoc := $1;
Exit;
end;
{ For NORMAL cooperative level we no longer need to provide an HWND }
ddrval := g_lpdd.SetCooperativeLevel(0, DDSCL_NORMAL);
if ddrval <> DD_OK then
begin
DebugLoc := $2;
Exit;
end;
if g_lpdd = nil then
begin
DebugLoc := $3;
Exit;
end;
{ Create the primary surface }
FillChar(ddsd, sizeof(ddsd), #0);
ddsd.dwSize := sizeof(ddsd);
ddsd.dwFlags := DDSD_CAPS;
ddsd.ddsCaps.dwCaps := DDSCAPS_PRIMARYSURFACE;
ddrval := g_lpdd.CreateSurface(ddsd, g_lpddsPrimary, nil);
if ddrval <> DD_OK then
begin
DebugLoc := $4;
Exit;
end;
{ Get driver capabilities to determine Overlay support }
FillChar(capsDrv, sizeof(capsDrv), #0);
capsDrv.dwSize := sizeof(capsDrv);
ddrval := g_lpdd.GetCaps(@capsDrv, nil);
if ddrval <> DD_OK then
begin
DebugLoc := $5;
Exit;
end;
{*******************************************************************
Does the driver support overlays in the current mode?
(Currently the DirectDraw emulation layer does not support overlays.
Overlay related APIs will fail without hardware support)
*******************************************************************}
if (capsDrv.dwCaps and DDCAPS_OVERLAY) = 0 then
begin
DebugLoc := $B;
Exit;
end;
{ Setup the overlay surface }
{ Init Direct3D }
FillChar(ddsdOverlay, sizeof(ddsdOverlay), #0);
ddsdOverlay.dwSize := sizeof(ddsdOverlay);
ddsdOverlay.dwFlags := DDSD_CAPS or DDSD_HEIGHT or DDSD_WIDTH or DDSD_PIXELFORMAT;
ddsdOverlay.dwBackBufferCount := 0;
ddsdOverlay.dwWidth := 800;
ddsdOverlay.dwHeight := 720;
ddsdOverlay.ddsCaps.dwCaps := DDSCAPS_OVERLAY or DDSCAPS_VIDEOMEMORY;
{*******************************************************************
Fills many possible pixel formats to be utilized.
The most widely supported seams to be YUV, so that one is
utilized by default
*******************************************************************}
{ Generic YUV }
pixelFormats[0].dwSize := SizeOf(DDPIXELFORMAT);
pixelFormats[0].dwFlags := DDPF_FOURCC;
pixelFormats[0].dwFourCC := DWORD(Byte('U') or (Byte('Y') shl 8) or (Byte('V') shl 16) or (Byte('Y') shl 24));
pixelFormats[0].dwYUVBitCount := 16;
{ RGB 16 bits depth 5-5-5 }
pixelFormats[1].dwSize := SizeOf(DDPIXELFORMAT);
pixelFormats[1].dwFlags := DDPF_RGB;
pixelFormats[1].dwFourCC := 0;
pixelFormats[1].dwRGBBitCount := 16;
pixelFormats[1].dwRBitMask := $7C00;
pixelFormats[1].dwGBitMask := $03E0;
pixelFormats[1].dwBBitMask := $001F;
{ RGB 16 bits depth 5-6-5 }
pixelFormats[2].dwSize := SizeOf(DDPIXELFORMAT);
pixelFormats[2].dwFlags := DDPF_RGB;
pixelFormats[2].dwFourCC := 0;
pixelFormats[2].dwRgbBitCount := 16;
pixelFormats[2].dwRBitMask := $F800;
pixelFormats[2].dwGBitMask := $07E0;
pixelFormats[2].dwBBitMask := $001F;
{ RGB 32 bits depth }
pixelFormats[3].dwSize := SizeOf(DDPIXELFORMAT);
pixelFormats[3].dwFlags := DDPF_RGB;
pixelFormats[3].dwFourCC := 0;
pixelFormats[3].dwRGBBitCount := 32;
pixelFormats[3].dwRBitMask := $00FF0000;
pixelFormats[3].dwGBitMask := $0000FF00;
pixelFormats[3].dwBBitMask := $000000FF;
ddsdOverlay.ddpfPixelFormat := pixelFormats[0];
ddrval := g_lpdd.CreateSurface(ddsdOverlay, g_lpddsOverlay, nil);
if ddrval <> DD_OK then
begin
DebugLoc := $C;
DebugInfo := ddrval;
Exit;
end;
if (g_lpddsOverlay = nil) then
begin
DebugLoc := $D;
Exit;
end;
{ Create a clipper for our window }
ddrval := g_lpdd.CreateClipper(0, g_lpClipper, nil);
if ddrval <> DD_OK then
begin
DebugLoc := $E;
Exit;
end;
Result := True;
end;
{*******************************************************************
* WndProc ()
*
* Message handling routine for the main window
*******************************************************************}
function WndProc(ahWnd: HWND; amessage: UINT; awParam: WPARAM; alParam: LPARAM): LResult; stdcall;
var
wmId, wmEvent: Integer;
ps: PAINTSTRUCT;
MyDC: HDC;
ptClient: POINT;
rectBlt: RECT;
addbfx: DDBltFX;
begin
Result := 0;
case amessage of
WM_PAINT:
begin
{ Attach the clipper to the primary surface for this operation }
// ddrval := g_lpddsPrimary.SetClipper(g_lpClipper);
MyDC := BeginPaint(ahWnd, @ps);
{ Fill the client area with colour key }
ptClient.x := ps.rcPaint.left;
ptClient.y := ps.rcPaint.top;
ClientToScreen(GetDesktopWindow, @ptClient);
rectBlt.left := ptClient.x;
rectBlt.top := ptClient.y;
ptClient.x := ps.rcPaint.right;
ptClient.y := ps.rcPaint.bottom;
ClientToScreen(GetDesktopWindow, @ptClient);
rectBlt.right := ptClient.x;
rectBlt.bottom := ptClient.y;
addbfx.dwSize := sizeof(DDBLTFX);
addbfx.dwFillColor := 0;
g_lpddsPrimary.Blt(
@rectBlt, nil, @rectBlt, DDBLT_COLORFILL or DDBLT_WAIT, @addbfx);
{ Get the DC from the overlay surface }
{ MyDC := 0;
ddrval := g_lpddsOverlay.GetDC(MyDC);
if ddrval <> DD_OK then
begin
DebugInfo := ddrval;
ShowError;
Exit;
end;
Windows.Rectangle(MyDC, 0, 0, 200, 200);}
EndPaint(ahWnd, @ps);
// ddrval := g_lpddsPrimary.SetClipper(nil);
end;
WM_DESTROY:
PostQuitMessage(0);
else
Result := DefWindowProc(ahWnd, amessage, awParam, alParam);
end;
end;
{*******************************************************************
* CreateMainWindow ()
*
* Creates the main window
*******************************************************************}
procedure CreateMainWindow;
var
wcex: WNDCLASSEX;
ahwnd: HWND;
MainWindowClassName: PChar;
begin
MainWindowClassName := 'OVERLAYS';
FillChar(wcex, sizeof(wcex), #0);
wcex.cbSize := sizeof(WNDCLASSEX);
wcex.style := CS_HREDRAW or CS_VREDRAW;
wcex.lpfnWndProc := @WndProc;
wcex.cbClsExtra := 0;
wcex.cbWndExtra := 0;
wcex.hInstance := hInstance;
wcex.hCursor := LoadCursor(0, IDC_ARROW);
wcex.hbrBackground := (COLOR_WINDOW+1);
wcex.lpszClassName := MainWindowClassName;
RegisterClassEx(@wcex);
ahWnd := CreateWindow(MainWindowClassName, 'Overlays Example', WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 100, 100, 0, 0, hInstance, nil);
ShowWindow(ahWnd, SW_SHOWNORMAL);
UpdateWindow(ahWnd);
end;
{*******************************************************************
* WndProc ()
*
* Message handling routine for the main window
*******************************************************************}
procedure ShowError;
begin
Windows.MessageBox(0, PChar('Loc: ' + IntToHex(DebugLoc, 8) + ' Info: ' + IntToHex(DebugInfo, 8)), 'Titulo', MB_ICONEXCLAMATION + MB_OK);
end;
{*******************************************************************
* Main program block
*******************************************************************}
var
Msg: TMsg;
begin
if not InitOverlays() then ShowError;
CreateMainWindow();
while Windows.GetMessage(@Msg, 0, 0, 0) do
begin
Windows.TranslateMessage(@msg);
Windows.DispatchMessage(@msg);
end;
end.
.
- Prev by Date: Re: rotation between two vectors
- Next by Date: d3d10 alt-enter
- Previous by thread: rotation between two vectors
- Next by thread: d3d10 alt-enter
- Index(es):
Relevant Pages
|