| 導購 | 订阅 | 在线投稿
分享
 
 
 

DircetDraw c/c++ 使用指導(一)

來源:互聯網網民  2006-12-17 09:28:33  評論

DircetDraw c/c++ 使用指導(一)

DircetDraw c/c++ 使用指導(一) DircetDraw c/c++ 使用指導

310cdt 譯

邊看邊譯,譯完就拿了上來,見笑了

這是一系列的DirectDraw的指南,教你一步步的去構建一個簡單的DirectDraw應用.這個指南用到了sdk包提供的很多DirectDraw的例子.這些例子展示了怎樣設置DirectDraw,怎樣用DirectDraw方法實現一般任務:

注意:這些指南中的例子是用c++寫的.如果你使用的是c編譯器,請進行適當的改變,以能進行成功的編譯.你需要把vtable和this指針添加到接口方法中.

1.DirectDraw基礎用法

要使用DirectDraw,你必須先創建一個代表計算機顯示接口的DirectDraw實例.然後,你就可以通過接口的方法來操縱這個對象.你可能會需要創建一個或更多的DirectDraw平面對象(DirectDraw surface object)的實例

來在圖形設備上顯示你的應用程序.

爲了演示這個,例子DDEx1 sample((SDK root)\Samples\Multimedia\DDraw\Src\Ddex1)演示了以下幾步:

step 1:創建一個DirectDraw對象

想創建一個DirectDraw對象的實例,你的應用程序必須在InitApp函數中使用DirectDrawCreateEx函數,就像例程ddex1中一樣.DirectDrawCreateEx函數包括4個參數.第一個是:顯示設備全局唯一標識(GUID).GUID大部分情況下是設爲NULL,選擇系統默認的顯示設備.第二個參數是:包含的是標示DirectDraw對象是否建立的指針的地址.第三個參數是IDirectDraw7接口的參考標示.必須設爲IID_IDirectDraw7.第四個參數是設置爲NULL的,是爲了將來的擴展做准備的.

以下的例子展示了怎樣創建DirectDraw對象,並判斷創建是否成功.

hRet = DirectDrawCreateEx(NULL, (VOID**)&g_pDD, IID_IDirectDraw7, NULL);

if(hRet == DD_OK)

{

// g_pDD is a valid DirectDraw object.

}

else

{

// The DirectDraw object could not be created.

}

step2:決定程序的行爲

在你改變顯示方法前,你必須至少在IDirectDraw7::SetCooperativeLevel函數中指定dwFlags參數(DDSCL_EXCLUSIVE 和 DDSCL_FULLSCREEN).這樣,你的應用程序就得到了顯示設備的全部控制權,其他的程序不能共享.DDSCL_FULLSCREEN讓你的應用程序在全屏幕模式下運行.你的程序覆蓋了桌面,並且只有你的程序能在屏幕上輸出.但是,桌面仍然是有效的.(按ALT+TAB切換到桌面)

下面的例子演示了SetCooperativeLevel函數的用法.

HRESULT hRet;

LPDIRECTDRAW7 g_pDD; // already created by DirectDrawCreateEx

hRet = g_pDD->SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);

if (hRet != DD_OK)

{

// Exclusive mode was successful.

}

else

{

// Exclusive mode was not successful.

// The application can still run, however.

}

如果 SetCooperativeLevel不返回DD_OK,你可以指定爲DDSCL_NORMAL繼續運行你的程序.但是,你的程序不再是獨占模式,而且,可能會無法完成你的一部分要求.在這種情況下,你最好顯示一個對話框讓用戶決定是否要繼續.

如果你設置的是全屏幕獨占合作級別,你必須把程序的窗口句柄傳遞給SetCooperativeLevel,這樣可以讓Windows有能力決定你的程序是否異常終止.

step3 :改變顯示模式

接下來,你可以用IDirectDraw7::SetDisplayMode函數來改變顯示模式.下面的例子將演示怎樣把顯示模式設置爲640 × 480 × 8 bits per pixel (bpp).

HRESULT hRet;

LPDIRECTDRAW7 g_pDD; // already created by DirectDrawCreateEx

hRet = g_pDD->SetDisplayMode(640, 480, 8, 0, 0);

if (hRet != DD_OK)

{

// The display mode changed successfully.

}

else

{

// The display mode cannot be changed.

// The mode is either not supported or

// another application has exclusive mode.

}

當你設置顯示模式的時候,你應該確定用戶的硬件是否支持這樣的模式.你可以設置一個能被大部分顯示適配器支持的標准的模式.例如:你的程序可以以640 × 480 × 8作爲備選模式,設計成爲可以在所有系統上運行.

注意:IDirectDraw7::SetDisplayMode返回一個DDERR INVALIDMODE錯誤值,如果顯示適配器無法切換到想要的模式時.你可以在試圖改變顯示模式前,用IDirectDraw7::EnumDisplayModes函數看一下用戶顯示適配器的能力.

step4:創建交換頁(flipping surface)

設置完顯示模式以後,你應該創建一個平面.例程:DDEx1用IDirectDraw7::SetCooperativeLevel 設置爲獨占模式.所以,你可以創建交換頁(flipping surfaces).如果你設置的是DDSCL_NORMAL模式,你可以創建一個可以塊移動(blit)的平面.創建交換頁(flipping surfaces)需要以下步驟:

(4.1)定義需求的平面:

第一步是以DDSURFACEDESC2結構定義一個需求的平面.下面的例子演示了結構的定義和標志位的設定:

// Create the primary surface with one back buffer.

ZeroMemory(&ddsd, sizeof(ddsd));

ddsd.dwSize = sizeof(ddsd);

ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;

ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP |

DDSCAPS_COMPLEX;

ddsd.dwBackBufferCount = 1;

在這個例子中,dwSize成員是DDSURFACEDESC2結構的大小.這是防止你用到的DirectDraw方法返回無效成員的錯誤.(dwSize是准備給將來的DDSURFACEDESC2結構的擴展用的)

dwFlags成員決定的DDSURFACEDESC2結構中那些成員將被填充有效的信息.例如在DDEx1中,dwFlags被設爲你想要用DDSCAPS結構(DDSD_CAPS)和你想創建一個後台緩沖(back buffer)(DDSD_BACKBUFFERCOUNT)

dwCaps成員在例子中標示一個將要在DDSCAPS結構中使用的標志位.在這種情況下,他指定一個主平面(primary surface DDSCAPS_PRIMARYSURFACE),一個交換頁(flipping surface DDSCAPS_FLIP),一個合成表面(complex surface DDSCAPS_COMPLEX).

最後,例子指定了一個後台緩沖.後台緩沖就是實際的繪圖操作先在那裏完成,然後,再快速的翻動(flip)到主平面(primary surface)上.在DDEx1中,後台緩沖的數目是1.其實,你要你的顯存允許,你想建幾個就建幾個.你想知道更多的關于創建大于1塊緩沖的信息,可以去看 "triple buffering".

創建的"平面"占用的存儲空間,可以是系統內存也可以是顯存.如果應用程序使用的空間超出了顯存,DirectDraw就會使用系統內存.(例如你指定多塊緩存在一個僅有1MB顯存的是配器上).你也可以這樣設置DDSCAPS結構的dwCaps成員,設成DDSCAPS_VIDEOMEMEORY或DDCAPS_SYSTEMMEMORY以達到只用顯存或只用內存.(如指定用顯存,而顯存不夠,IDirectDraw7::CreateSurface返回一個DDERR_OUTOFVIDEOMEMORY錯誤)

(4.2)創建平面

在填充完DDSURFACEDESC2結構後,你就可以用他和g_pDD指針(DirectDrawCreateEx函數創建的DirectDraw對象的指針)調用IDirectDraw7::CreateSurface方法,就像下面 :

hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSPrimary, NULL);

if (hRet != DD_OK)

{

// g_pDDSPrimary points to the new surface.

}

else

{

// The surface was not created.

return FALSE;

}

g_pDDSPrimary參數將指向由CreateSurface函數返回的主平面(primary surface)的地址,如果調用成功的話.

指向主平面(primary surface)的指針有效後,就可以調用IDirectDrawSurface7::GetAttachedSurface方法去得到一個指向緩沖的指針.如下:

ZeroMemory(&ddscaps, sizeof(ddscaps));

ddscaps.dwCaps = DDSCAPS_BACKBUFFER;

hRet = g_pDDSPrimary->GetAttachedSurface(&ddscaps, &g_pDDSBack);

if (hRet != DD_OK)

{

// g_pDDSBack points to the back buffer.

}

else

{

return FALSE;

}

如果IDirectDrawSurface7::GetAttachedSurface調用成功,g_pDDSBack參數將指向緩存區.

step5:在平面上輸出

在主平面(primary surface)和後台緩沖(back buffer)創建完成後,例子DDEx1用windows標准GDI函數輸出了一些文本在緩沖上.如下:

if (g_pDDSBack->GetDC(&hdc) == DD_OK)

{

SetBkColor(hdc, RGB(0, 0, 255));

SetTextColor(hdc, RGB(255, 255, 0));

if (phase)

{

GetClientRect(hWnd, &rc);

GetTextExtentPoint(hdc, szMsg, lstrlen(szMsg), &size);

TextOut(hdc, (rc.right - size.cx) / 2, (rc.bottom - size.cy) / 2,

szMsg, sizeof(szMsg) - 1);

TextOut(hdc, 0, 0, szFrontMsg, lstrlen(szFrontMsg));

phase = 0;

}

else

{

TextOut(hdc, 0, 0, szBackMsg, lstrlen(szBackMsg));

phase = 1;

}

g_pDDSBack->ReleaseDC(hdc);

}

這個例子使用the IDirectDrawSurface7::GetDC方法獲得設備上下文的句柄,並且,爲了准備寫入,將緩沖上鎖.如果你不准備用需要設備上下文句柄的windows函數,你可以使用IDirectDrawSurface7::Lock IDirectDrawSurface7::Unlock方法加解鎖.

接下來,phase變量決定了應該輸出到主緩存消息(primary buffer message)還是後台緩存消息(back buffer message).如果phase=1,輸出

主緩存消息,且設phase=0.如果phase=0,輸出後台緩存消息,且設phase=1.

當消息輸出到緩存區後,用IDirectDrawSurface7::ReleaseDC 方法將緩存區解鎖.

對創建平面的內存上鎖,是保證你的程序和系統不能同時對此內存進行存取.這防止你寫入"平面"內存事發生錯誤.另外,不對"平面"內存解鎖,你的程序將無法翻轉平面.

平面被加鎖之後,例子中用了標准windowsGDI函數:SetBkColor設置背景色,SetTextColor設置在背景上顯示的字的顔色,用TextOut在"表面"上輸出文字和背景色.

當文字被輸出到緩存之後,例子應用IDirectDrawSurface7::ReleaseDC方法解鎖"表面"並且釋放句柄.不論在什麽時候你的程序完成了對緩存的寫入,一定要調用IDirectDrawSurface7::ReleaseDC 或IDirectDrawSurface7::Unlock之一,具體用哪個,由你的程序而定.不解鎖,你的程序將不能翻轉平面.

注意:用IDirectDrawSurface7::Unlock對"平面"解鎖後,指向"平面"的指針將會無效.你必須再用IDirectDrawSurface7::lock去獲得一個有效的指針.

step:6 翻轉平面

在DDEx1中,WM_TIMER消息引發從緩存到主平面的翻轉.當"平面"內存解鎖後,你就可以用IDirectDrawSurface7::Flip方法實現從緩存到主平面的翻轉.如下:

case WM_TIMER:

// Update and flip surfaces

if (g_bActive && TIMER_ID == wParam)

{

UpdateFrame(hWnd);

while (TRUE)

{

hRet = g_pDDSPrimary->Flip(NULL, 0);

if (hRet == DD_OK)

break;

if (hRet == DDERR_SURFACELOST)

{

hRet = g_pDDSPrimary->Restore();

if (hRet != DD_OK)

break;

}

if (hRet != DDERR_WASSTILLDRAWING)

break;

}

}

break;

在例子中,g_pDDSPrimary參數指示主平面和與他連接的緩存.當IDirectDrawSurface7::Flip被調用,前後平面將會交換(只是交換指針,沒有實際的數據交換).如果翻轉成功,返回DD_OK,跳出循環.

如果翻轉返回的是DDERR_SURFACELOST值,就試圖用IDirectDrawSurface7::Restore 方法保存平面.如果保存成功,程序循環到調用IDirectDrawSurface7::Flip,再試一次.如果保存不成功,程序跳出循環,返回一個錯誤.

注意:當你調用IDirectDrawSurface7::Flip 時,翻轉動作並不能馬上完成.如果,前一個翻轉動作還沒有完成,IDirectDrawSurface7::Flip 會返回DDERR_WASSTILLDRAWING.在這個例子中,IDirectDrawSurface7::Flip會一直調用直到返回DD_OK.

step7:釋放DirectDraw對象

當你按下F12鍵時,例子DDEx1將在退出程序前處理WM_DESTROY消息.這個消息將調用ReleaseAllObjects函數,這個函數包括了多個Release調用.像下面一樣:

static void

ReleaseAllObjects(void)

{

if (g_pDD != NULL)

{

if (g_pDDSPrimary != NULL)

{

g_pDDSPrimary->Release();

g_pDDSPrimary = NULL;

}

g_pDD->Release();

g_pDD = NULL;

}

}

這個程序檢測DirectDraw對象的指針g_pDD和DirectDraw平面對象的指針g_pDDSPrimary是否爲NULL.然後,調用IDirectDrawSurface7::Release方法令DirectDraw平面對象的reference count(可以認爲是創建的對象的數目)數減1,這使得reference count減爲0,DirectDraw平面對象就釋放了.然後,還需將他的指針值設爲NULL.接下來,程序調用IDirectDraw7::Release,同樣是令DirectDraw的reference count減1,然後然後....全銷毀.

 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
DircetDraw c/c++ 使用指導(一) DircetDraw c/c++ 使用指導(一) DircetDraw c/c++ 使用指導 310cdt 譯 邊看邊譯,譯完就拿了上來,見笑了 這是一系列的DirectDraw的指南,教你一步步的去構建一個簡單的DirectDraw應用.這個指南用到了sdk包提供的很多DirectDraw的例子.這些例子展示了怎樣設置DirectDraw,怎樣用DirectDraw方法實現一般任務: 注意:這些指南中的例子是用c++寫的.如果你使用的是c編譯器,請進行適當的改變,以能進行成功的編譯.你需要把vtable和this指針添加到接口方法中. 1.DirectDraw基礎用法 要使用DirectDraw,你必須先創建一個代表計算機顯示接口的DirectDraw實例.然後,你就可以通過接口的方法來操縱這個對象.你可能會需要創建一個或更多的DirectDraw平面對象(DirectDraw surface object)的實例 來在圖形設備上顯示你的應用程序. 爲了演示這個,例子DDEx1 sample((SDK root)\Samples\Multimedia\DDraw\Src\Ddex1)演示了以下幾步: step 1:創建一個DirectDraw對象 想創建一個DirectDraw對象的實例,你的應用程序必須在InitApp函數中使用DirectDrawCreateEx函數,就像例程ddex1中一樣.DirectDrawCreateEx函數包括4個參數.第一個是:顯示設備全局唯一標識(GUID).GUID大部分情況下是設爲NULL,選擇系統默認的顯示設備.第二個參數是:包含的是標示DirectDraw對象是否建立的指針的地址.第三個參數是IDirectDraw7接口的參考標示.必須設爲IID_IDirectDraw7.第四個參數是設置爲NULL的,是爲了將來的擴展做准備的. 以下的例子展示了怎樣創建DirectDraw對象,並判斷創建是否成功. hRet = DirectDrawCreateEx(NULL, (VOID**)&g_pDD, IID_IDirectDraw7, NULL); if(hRet == DD_OK) { // g_pDD is a valid DirectDraw object. } else { // The DirectDraw object could not be created. } step2:決定程序的行爲 在你改變顯示方法前,你必須至少在IDirectDraw7::SetCooperativeLevel函數中指定dwFlags參數(DDSCL_EXCLUSIVE 和 DDSCL_FULLSCREEN).這樣,你的應用程序就得到了顯示設備的全部控制權,其他的程序不能共享.DDSCL_FULLSCREEN讓你的應用程序在全屏幕模式下運行.你的程序覆蓋了桌面,並且只有你的程序能在屏幕上輸出.但是,桌面仍然是有效的.(按ALT+TAB切換到桌面) 下面的例子演示了SetCooperativeLevel函數的用法. HRESULT hRet; LPDIRECTDRAW7 g_pDD; // already created by DirectDrawCreateEx hRet = g_pDD->SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); if (hRet != DD_OK) { // Exclusive mode was successful. } else { // Exclusive mode was not successful. // The application can still run, however. } 如果 SetCooperativeLevel不返回DD_OK,你可以指定爲DDSCL_NORMAL繼續運行你的程序.但是,你的程序不再是獨占模式,而且,可能會無法完成你的一部分要求.在這種情況下,你最好顯示一個對話框讓用戶決定是否要繼續. 如果你設置的是全屏幕獨占合作級別,你必須把程序的窗口句柄傳遞給SetCooperativeLevel,這樣可以讓Windows有能力決定你的程序是否異常終止. step3 :改變顯示模式 接下來,你可以用IDirectDraw7::SetDisplayMode函數來改變顯示模式.下面的例子將演示怎樣把顯示模式設置爲640 × 480 × 8 bits per pixel (bpp). HRESULT hRet; LPDIRECTDRAW7 g_pDD; // already created by DirectDrawCreateEx hRet = g_pDD->SetDisplayMode(640, 480, 8, 0, 0); if (hRet != DD_OK) { // The display mode changed successfully. } else { // The display mode cannot be changed. // The mode is either not supported or // another application has exclusive mode. } 當你設置顯示模式的時候,你應該確定用戶的硬件是否支持這樣的模式.你可以設置一個能被大部分顯示適配器支持的標准的模式.例如:你的程序可以以640 × 480 × 8作爲備選模式,設計成爲可以在所有系統上運行. 注意:IDirectDraw7::SetDisplayMode返回一個DDERR INVALIDMODE錯誤值,如果顯示適配器無法切換到想要的模式時.你可以在試圖改變顯示模式前,用IDirectDraw7::EnumDisplayModes函數看一下用戶顯示適配器的能力. step4:創建交換頁(flipping surface) 設置完顯示模式以後,你應該創建一個平面.例程:DDEx1用IDirectDraw7::SetCooperativeLevel 設置爲獨占模式.所以,你可以創建交換頁(flipping surfaces).如果你設置的是DDSCL_NORMAL模式,你可以創建一個可以塊移動(blit)的平面.創建交換頁(flipping surfaces)需要以下步驟: (4.1)定義需求的平面: 第一步是以DDSURFACEDESC2結構定義一個需求的平面.下面的例子演示了結構的定義和標志位的設定: // Create the primary surface with one back buffer. ZeroMemory(&ddsd, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; ddsd.dwBackBufferCount = 1; 在這個例子中,dwSize成員是DDSURFACEDESC2結構的大小.這是防止你用到的DirectDraw方法返回無效成員的錯誤.(dwSize是准備給將來的DDSURFACEDESC2結構的擴展用的) dwFlags成員決定的DDSURFACEDESC2結構中那些成員將被填充有效的信息.例如在DDEx1中,dwFlags被設爲你想要用DDSCAPS結構(DDSD_CAPS)和你想創建一個後台緩沖(back buffer)(DDSD_BACKBUFFERCOUNT) dwCaps成員在例子中標示一個將要在DDSCAPS結構中使用的標志位.在這種情況下,他指定一個主平面(primary surface DDSCAPS_PRIMARYSURFACE),一個交換頁(flipping surface DDSCAPS_FLIP),一個合成表面(complex surface DDSCAPS_COMPLEX). 最後,例子指定了一個後台緩沖.後台緩沖就是實際的繪圖操作先在那裏完成,然後,再快速的翻動(flip)到主平面(primary surface)上.在DDEx1中,後台緩沖的數目是1.其實,你要你的顯存允許,你想建幾個就建幾個.你想知道更多的關于創建大于1塊緩沖的信息,可以去看 "triple buffering". 創建的"平面"占用的存儲空間,可以是系統內存也可以是顯存.如果應用程序使用的空間超出了顯存,DirectDraw就會使用系統內存.(例如你指定多塊緩存在一個僅有1MB顯存的是配器上).你也可以這樣設置DDSCAPS結構的dwCaps成員,設成DDSCAPS_VIDEOMEMEORY或DDCAPS_SYSTEMMEMORY以達到只用顯存或只用內存.(如指定用顯存,而顯存不夠,IDirectDraw7::CreateSurface返回一個DDERR_OUTOFVIDEOMEMORY錯誤) (4.2)創建平面 在填充完DDSURFACEDESC2結構後,你就可以用他和g_pDD指針(DirectDrawCreateEx函數創建的DirectDraw對象的指針)調用IDirectDraw7::CreateSurface方法,就像下面 : hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSPrimary, NULL); if (hRet != DD_OK) { // g_pDDSPrimary points to the new surface. } else { // The surface was not created. return FALSE; } g_pDDSPrimary參數將指向由CreateSurface函數返回的主平面(primary surface)的地址,如果調用成功的話. 指向主平面(primary surface)的指針有效後,就可以調用IDirectDrawSurface7::GetAttachedSurface方法去得到一個指向緩沖的指針.如下: ZeroMemory(&ddscaps, sizeof(ddscaps)); ddscaps.dwCaps = DDSCAPS_BACKBUFFER; hRet = g_pDDSPrimary->GetAttachedSurface(&ddscaps, &g_pDDSBack); if (hRet != DD_OK) { // g_pDDSBack points to the back buffer. } else { return FALSE; } 如果IDirectDrawSurface7::GetAttachedSurface調用成功,g_pDDSBack參數將指向緩存區. step5:在平面上輸出 在主平面(primary surface)和後台緩沖(back buffer)創建完成後,例子DDEx1用windows標准GDI函數輸出了一些文本在緩沖上.如下: if (g_pDDSBack->GetDC(&hdc) == DD_OK) { SetBkColor(hdc, RGB(0, 0, 255)); SetTextColor(hdc, RGB(255, 255, 0)); if (phase) { GetClientRect(hWnd, &rc); GetTextExtentPoint(hdc, szMsg, lstrlen(szMsg), &size); TextOut(hdc, (rc.right - size.cx) / 2, (rc.bottom - size.cy) / 2, szMsg, sizeof(szMsg) - 1); TextOut(hdc, 0, 0, szFrontMsg, lstrlen(szFrontMsg)); phase = 0; } else { TextOut(hdc, 0, 0, szBackMsg, lstrlen(szBackMsg)); phase = 1; } g_pDDSBack->ReleaseDC(hdc); } 這個例子使用the IDirectDrawSurface7::GetDC方法獲得設備上下文的句柄,並且,爲了准備寫入,將緩沖上鎖.如果你不准備用需要設備上下文句柄的windows函數,你可以使用IDirectDrawSurface7::Lock IDirectDrawSurface7::Unlock方法加解鎖. 接下來,phase變量決定了應該輸出到主緩存消息(primary buffer message)還是後台緩存消息(back buffer message).如果phase=1,輸出 主緩存消息,且設phase=0.如果phase=0,輸出後台緩存消息,且設phase=1. 當消息輸出到緩存區後,用IDirectDrawSurface7::ReleaseDC 方法將緩存區解鎖. 對創建平面的內存上鎖,是保證你的程序和系統不能同時對此內存進行存取.這防止你寫入"平面"內存事發生錯誤.另外,不對"平面"內存解鎖,你的程序將無法翻轉平面. 平面被加鎖之後,例子中用了標准windowsGDI函數:SetBkColor設置背景色,SetTextColor設置在背景上顯示的字的顔色,用TextOut在"表面"上輸出文字和背景色. 當文字被輸出到緩存之後,例子應用IDirectDrawSurface7::ReleaseDC方法解鎖"表面"並且釋放句柄.不論在什麽時候你的程序完成了對緩存的寫入,一定要調用IDirectDrawSurface7::ReleaseDC 或IDirectDrawSurface7::Unlock之一,具體用哪個,由你的程序而定.不解鎖,你的程序將不能翻轉平面. 注意:用IDirectDrawSurface7::Unlock對"平面"解鎖後,指向"平面"的指針將會無效.你必須再用IDirectDrawSurface7::lock去獲得一個有效的指針. step:6 翻轉平面 在DDEx1中,WM_TIMER消息引發從緩存到主平面的翻轉.當"平面"內存解鎖後,你就可以用IDirectDrawSurface7::Flip方法實現從緩存到主平面的翻轉.如下: case WM_TIMER: // Update and flip surfaces if (g_bActive && TIMER_ID == wParam) { UpdateFrame(hWnd); while (TRUE) { hRet = g_pDDSPrimary->Flip(NULL, 0); if (hRet == DD_OK) break; if (hRet == DDERR_SURFACELOST) { hRet = g_pDDSPrimary->Restore(); if (hRet != DD_OK) break; } if (hRet != DDERR_WASSTILLDRAWING) break; } } break; 在例子中,g_pDDSPrimary參數指示主平面和與他連接的緩存.當IDirectDrawSurface7::Flip被調用,前後平面將會交換(只是交換指針,沒有實際的數據交換).如果翻轉成功,返回DD_OK,跳出循環. 如果翻轉返回的是DDERR_SURFACELOST值,就試圖用IDirectDrawSurface7::Restore 方法保存平面.如果保存成功,程序循環到調用IDirectDrawSurface7::Flip,再試一次.如果保存不成功,程序跳出循環,返回一個錯誤. 注意:當你調用IDirectDrawSurface7::Flip 時,翻轉動作並不能馬上完成.如果,前一個翻轉動作還沒有完成,IDirectDrawSurface7::Flip 會返回DDERR_WASSTILLDRAWING.在這個例子中,IDirectDrawSurface7::Flip會一直調用直到返回DD_OK. step7:釋放DirectDraw對象 當你按下F12鍵時,例子DDEx1將在退出程序前處理WM_DESTROY消息.這個消息將調用ReleaseAllObjects函數,這個函數包括了多個Release調用.像下面一樣: static void ReleaseAllObjects(void) { if (g_pDD != NULL) { if (g_pDDSPrimary != NULL) { g_pDDSPrimary->Release(); g_pDDSPrimary = NULL; } g_pDD->Release(); g_pDD = NULL; } } 這個程序檢測DirectDraw對象的指針g_pDD和DirectDraw平面對象的指針g_pDDSPrimary是否爲NULL.然後,調用IDirectDrawSurface7::Release方法令DirectDraw平面對象的reference count(可以認爲是創建的對象的數目)數減1,這使得reference count減爲0,DirectDraw平面對象就釋放了.然後,還需將他的指針值設爲NULL.接下來,程序調用IDirectDraw7::Release,同樣是令DirectDraw的reference count減1,然後然後....全銷毀.
󰈣󰈤
王朝萬家燈火計劃
期待原創作者加盟
 
 
 
>>返回首頁<<
 
 
 
 
 
 熱帖排行
 
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有