بسم الله الرحمن الرحيم
الاخوة الاعضاء فى منتدى الجرافيكس
اقوم الان بتصميم Frame كل البرامج التى
اكتبها ب Direct3D9.0 لكن وا جهتنى مشكلة
واحدة, هى ان عند تصغير النافذة تقوم بتعليق
الجهاز. ارفق لكم الملف.
بسم الله الرحمن الرحيم
الاخوة الاعضاء فى منتدى الجرافيكس
اقوم الان بتصميم Frame كل البرامج التى
اكتبها ب Direct3D9.0 لكن وا جهتنى مشكلة
واحدة, هى ان عند تصغير النافذة تقوم بتعليق
الجهاز. ارفق لكم الملف.
لم استطع ارفاق الملف لذا ها هو
#include "windows.h"
#include "d3d9.h"
#include "d3dx9.h"
#include "dxerr9.h"
/*******************************************************/
/***************Direct3D Objects Here*******************/
LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_pD3DDevice = NULL;
/*******************************************************/
/*******************************************************/
/*******************************************************/
/***************ALL Normal Variables *******************/
HWND g_hApplicationWindow;
/*******************************************************/
/*******************************************************/
void AppLoop();
void AppShutDown();
HRESULT InitD3D();
HRESULT Render();
HRESULT ValidateDevice();
HRESULT RestoreDeviceObjects();
HRESULT InvalidateDeviceObjects();
HRESULT D3DError(HRESULT hrCode, int nLine, char* szFile, char* szExtraInfo);
#define SAFE_RELEASE(X) (X)->Release(); (X) = NULL
struct D3DCURRENTSETTINGS
{
int m_nDeviceHeight;
int m_nDeviceWidth;
float m_fScreenAspect;
BOOL m_bWindowed;
BOOL m_bMultiSampling;
D3DFORMAT m_D3DFormat;
D3DPRESENT_PARAMETERS m_PresentParams;
BOOL SetAspect()
{
if(m_nDeviceHeight == 0) return FALSE;
m_fScreenAspect = (float)m_nDeviceWidth/(float)m_nDeviceHeight;
return TRUE;
}
};
D3DCURRENTSETTINGS g_D3DSettings;
LRESULT CALLBACK MsgProc(HWND hWnd,UINT uMsg,WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_CLOSE:
::DestroyWindow(hWnd);
return 0;
break;
case WM_DESTROY:
::PostQuitMessage(0);
return 0;
case WM_SIZE:
{
if( g_pD3DDevice != NULL && wParam != SIZE_MINIMIZED )
{
InvalidateDeviceObjects();
g_D3DSettings.m_PresentParams.BackBufferWidth = LOWORD(lParam);
g_D3DSettings.m_PresentParams.BackBufferHeight = HIWORD(lParam);
HRESULT rslt = g_pD3DDevice->Reset( &g_D3DSettings.m_PresentParams );
if( FAILED(rslt) )
{
D3DError(rslt,__LINE__,__FILE__,"Failed To Reet the device during resizing");
::PostQuitMessage(0);
}
RestoreDeviceObjects();
}
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
default:
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// Register the window class
WNDCLASSEX wc;
ZeroMemory(&wc, sizeof(WNDCLASSEX));
wc.cbSize=sizeof(WNDCLASSEX); // size of the window struct in bytes
wc.style=CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // window styles to use
wc.lpfnWndProc=MsgProc; // function name of event handler
wc.hInstance=hInstance; // handle to this apps instance
wc.hbrBackground=(HBRUSH)GetStockObject(GRAY_BRUSH);// background colour of window
wc.hIcon= LoadIcon(NULL, IDI_APPLICATION); // icon for the app window
wc.hIconSm=LoadIcon(NULL, IDI_APPLICATION); // icon when minimized to taskbar
wc.hCursor=LoadCursor(NULL, IDC_ARROW); // cursor to use for this window
wc.lpszClassName="MY_WINDOW_CLASS_NAME"; // name for this class
RegisterClassEx( &wc );
// Create the application's window
g_D3DSettings.m_nDeviceWidth = 600;
g_D3DSettings.m_nDeviceHeight= 400;
g_D3DSettings.SetAspect();
g_hApplicationWindow = CreateWindow("MY_WINDOW_CLASS_NAME", "MY WINDOW TITLE",
WS_OVERLAPPEDWINDOW, 100, 100, 640, 480,
NULL, NULL, wc.hInstance, NULL );
// Show the window
ShowWindow( g_hApplicationWindow, nCmdShow );
UpdateWindow( g_hApplicationWindow );
HRESULT rslt = InitD3D();
if(FAILED(rslt))
{
D3DError(rslt,__LINE__,__FILE__,"InitD3D Failed");
return rslt;
}
// Enter the message loop
MSG msg;
ZeroMemory( &msg, sizeof(msg) );
while( msg.message!=WM_QUIT )
{
if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
AppLoop();
}
}
AppShutDown();
UnregisterClass( "MY_CLASS_NAME", wc.hInstance );
return 0;
}
HRESULT InitD3D()
{
g_pD3D=Direct3DCreate9(D3D_SDK_VERSION);
if(g_pD3D==NULL)
{
return E_FAIL;
}
// Populate our struct with how we want to set up D3D...
g_D3DSettings.m_bWindowed=TRUE;
g_D3DSettings.m_bMultiSampling=FALSE;
g_D3DSettings.m_D3DFormat=D3DFMT_X8R8G8B8;
////////////////////////////////////////////////////
/////////////Time To Prepare Our Device/////////////
D3DPRESENT_PARAMETERS d3dpp;
D3DDISPLAYMODE d3ddm;
g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddm);
ZeroMemory(&d3dpp,sizeof(D3DPRESENT_PARAMETERS));
d3dpp.BackBufferWidth = g_D3DSettings.m_nDeviceWidth;
d3dpp.BackBufferHeight = g_D3DSettings.m_nDeviceHeight;
d3dpp.BackBufferFormat = g_D3DSettings.m_bWindowed ? d3ddm.Format : g_D3DSettings.m_D3DFormat;
d3dpp.hDeviceWindow=g_hApplicationWindow;
d3dpp.Windowed=g_D3DSettings.m_bWindowed;
d3dpp.BackBufferCount=1;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
if(g_D3DSettings.m_bMultiSampling)
{
if( SUCCEEDED(g_pD3D->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
d3dpp.BackBufferFormat,
g_D3DSettings.m_bWindowed,
D3DMULTISAMPLE_2_SAMPLES, NULL)))
{
d3dpp.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
}
else
d3dpp.MultiSampleType=D3DMULTISAMPLE_NONE;
}
else
d3dpp.MultiSampleType=D3DMULTISAMPLE_NONE;
d3dpp.EnableAutoDepthStencil=TRUE;
d3dpp.AutoDepthStencilFormat=D3DFMT_D16;
d3dpp.FullScreen_RefreshRateInHz=0;
d3dpp.PresentationInterval = g_D3DSettings.m_bWindowed ? 0 : D3DPRESENT_INTERVAL_IMMEDIATE;
d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
HRESULT rslt=g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hApplicationWindow,
D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDevice);
if(FAILED(rslt))
{
rslt=g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hApplicationWindow,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDevice);
if(FAILED(rslt))
{
return E_FAIL;
}
}
g_D3DSettings.m_PresentParams=d3dpp;
if(g_D3DSettings.m_bWindowed)
g_D3DSettings.m_D3DFormat=d3dpp.BackBufferFormat;
return RestoreDeviceObjects();
}
HRESULT Render()
{
if(!g_pD3DDevice) return E_FAIL;
HRESULT rslt = ValidateDevice();
if(FAILED(rslt)) return rslt;
g_pD3DDevice->Clear(0,0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,55), 0.0f, 0);
rslt = g_pD3DDevice->BeginScene();
if(FAILED(rslt)) return rslt;
g_pD3DDevice->EndScene();
g_pD3DDevice->Present(NULL,NULL,NULL,NULL);
return S_OK;
}
HRESULT ValidateDevice()
{
HRESULT rslt = g_pD3DDevice->TestCooperativeLevel();
if(FAILED(rslt))
{
if(rslt == D3DERR_DEVICELOST)
return E_FAIL;
if(rslt == D3DERR_DEVICENOTRESET)
{
InvalidateDeviceObjects();
g_pD3DDevice->Reset(&g_D3DSettings.m_PresentParams);
RestoreDeviceObjects();
}
}
return S_OK;
}
HRESULT RestoreDeviceObjects()
{
return S_OK;
}
HRESULT InvalidateDeviceObjects()
{
return S_OK;
}
void AppLoop()
{
HRESULT rslt;
rslt = Render();
if(FAILED(rslt)) D3DError(rslt,__LINE__,__FILE__,"Render() Has Failed");
}
void AppShutDown()
{
InvalidateDeviceObjects();
SAFE_RELEASE(g_pD3D);
SAFE_RELEASE(g_pD3DDevice);
}
HRESULT D3DError(HRESULT hrCode, int nLine, char* szFile, char* szExtraInfo)
{
::OutputDebugString("--------------------------D3DError Has Been Called---------------------------\n");
char pszError[256];
wsprintf(pszError, "The following error occurred on line %d of %s\n", nLine, szFile);
::OutputDebugString(pszError);
::OutputDebugString(DXGetErrorString9(hrCode));
::OutputDebugString("\n");
if(szExtraInfo)
{
::OutputDebugString("Extra information: ");
::OutputDebugString(szExtraInfo);
::OutputDebugString("\n");
}
return hrCode;
}السلام عليكم ,,
نأسف على التأخير ,,
المشكلة أن حلقة الرسائل عندما لايكون هناك أي حدث في صف الرسائل ,, تستدعى الدالة AppLoop() ,, ليعمل البرنامج ,, والمشكلة أنه اذا لم يكن هناك دالة في بلوك ال else في كما في الكود التالي ,, سيعلق البرنامج ,,
if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
}كودك المكتوب كالتالي :
if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
AppLoop();
}حيث أن بلوك ال else فيه استدعاء لتنفيذ ال AppLoop ,, وعند تصغير البرنامج فان الدالة AppLoop لن تفعل شيئا في الواقع لأنه لاتوجد مساحة للعرض كما فهمت أنا ولم أتعمق في الكود أصلا ,,
لكن يكفي أن تسكت البرنامج وقت تصغير البرنامج لكي لايفعل شيئا ويعود ليعمل فور تكبير النافذة مباشرة ,, لأنه في الواقع لايفعل شيئا حقا عند تصغير النافذة فكتبت الكود التالي في بلوك ال else :
if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
if(!minimized)
AppLoop();
else Sleep(10);
}حيث المتغير minimized يصبح true عند تصغير البرنامج ثم يصبح false عندما يعود للوضع الطبيعي مرة أخرى ,,
خذ الكود النهائي :
#include "windows.h"
#include "d3d9.h"
#include "d3dx9.h"
//#include "dxerr9.h"
#pragma comment(lib,"d3d9.lib")
//#pragma comment(lib,"d3dX9.lib")
bool minimized=false;
/*******************************************************/
/***************Direct3D Objects Here*******************/
LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_pD3DDevice = NULL;
/*******************************************************/
/*******************************************************/
/*******************************************************/
/***************ALL Normal Variables *******************/
HWND g_hApplicationWindow;
/*******************************************************/
/*******************************************************/
void AppLoop();
void AppShutDown();
HRESULT InitD3D();
HRESULT Render();
HRESULT ValidateDevice();
HRESULT RestoreDeviceObjects();
HRESULT InvalidateDeviceObjects();
HRESULT D3DError(HRESULT hrCode, int nLine, char* szFile, char* szExtraInfo);
#define SAFE_RELEASE(X) (X)->Release(); (X) = NULL
struct D3DCURRENTSETTINGS
{
int m_nDeviceHeight;
int m_nDeviceWidth;
float m_fScreenAspect;
BOOL m_bWindowed;
BOOL m_bMultiSampling;
D3DFORMAT m_D3DFormat;
D3DPRESENT_PARAMETERS m_PresentParams;
BOOL SetAspect()
{
if(m_nDeviceHeight == 0) return FALSE;
m_fScreenAspect = (float)m_nDeviceWidth/(float)m_nDeviceHeight;
return TRUE;
}
};
D3DCURRENTSETTINGS g_D3DSettings;
LRESULT CALLBACK MsgProc(HWND hWnd,UINT uMsg,WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_CLOSE:
::DestroyWindow(hWnd);
return 0;
break;
case WM_DESTROY:
::PostQuitMessage(0);
return 0;
case WM_SIZE:
{
if( g_pD3DDevice != NULL && wParam != SIZE_MINIMIZED )
{minimized=false;
InvalidateDeviceObjects();
g_D3DSettings.m_PresentParams.BackBufferWidth = LOWORD(lParam);
g_D3DSettings.m_PresentParams.BackBufferHeight = HIWORD(lParam);
HRESULT rslt = g_pD3DDevice->Reset( &g_D3DSettings.m_PresentParams );
if( FAILED(rslt) )
{
D3DError(rslt,__LINE__,__FILE__,"Failed To Reet the device during resizing");
::PostQuitMessage(0);
}
RestoreDeviceObjects();
}
if(wParam==SIZE_MINIMIZED)
{
minimized=true;
}
if(wParam==SIZE_MAXIMIZED)
{
}
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
default:
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// Register the window class
WNDCLASSEX wc;
ZeroMemory(&wc, sizeof(WNDCLASSEX));
wc.cbSize=sizeof(WNDCLASSEX); // size of the window struct in bytes
wc.style=CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // window styles to use
wc.lpfnWndProc=MsgProc; // function name of event handler
wc.hInstance=hInstance; // handle to this apps instance
wc.hbrBackground=(HBRUSH)GetStockObject(GRAY_BRUSH);// background colour of window
wc.hIcon= LoadIcon(NULL, IDI_APPLICATION); // icon for the app window
wc.hIconSm=LoadIcon(NULL, IDI_APPLICATION); // icon when minimized to taskbar
wc.hCursor=LoadCursor(NULL, IDC_ARROW); // cursor to use for this window
wc.lpszClassName="MY_WINDOW_CLASS_NAME"; // name for this class
RegisterClassEx( &wc );
// Create the application's window
g_D3DSettings.m_nDeviceWidth = 600;
g_D3DSettings.m_nDeviceHeight= 400;
g_D3DSettings.SetAspect();
g_hApplicationWindow = CreateWindow("MY_WINDOW_CLASS_NAME", "MY WINDOW TITLE",
WS_OVERLAPPEDWINDOW, 100, 100, 640, 480,
NULL, NULL, wc.hInstance, NULL );
// Show the window
ShowWindow( g_hApplicationWindow, nCmdShow );
UpdateWindow( g_hApplicationWindow );
HRESULT rslt = InitD3D();
if(FAILED(rslt))
{
D3DError(rslt,__LINE__,__FILE__,"InitD3D Failed");
return rslt;
}
// Enter the message loop
MSG msg;
ZeroMemory( &msg, sizeof(msg) );
while( msg.message!=WM_QUIT )
{
if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
if(!minimized)
AppLoop();
else Sleep(10);
}
}
AppShutDown();
UnregisterClass( "MY_CLASS_NAME", wc.hInstance );
return 0;
}
HRESULT InitD3D()
{
g_pD3D=Direct3DCreate9(D3D_SDK_VERSION);
if(g_pD3D==NULL)
{
return E_FAIL;
}
// Populate our struct with how we want to set up D3D...
g_D3DSettings.m_bWindowed=TRUE;
g_D3DSettings.m_bMultiSampling=FALSE;
g_D3DSettings.m_D3DFormat=D3DFMT_X8R8G8B8;
////////////////////////////////////////////////////
/////////////Time To Prepare Our Device/////////////
D3DPRESENT_PARAMETERS d3dpp;
D3DDISPLAYMODE d3ddm;
g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddm);
ZeroMemory(&d3dpp,sizeof(D3DPRESENT_PARAMETERS));
d3dpp.BackBufferWidth = g_D3DSettings.m_nDeviceWidth;
d3dpp.BackBufferHeight = g_D3DSettings.m_nDeviceHeight;
d3dpp.BackBufferFormat = g_D3DSettings.m_bWindowed ? d3ddm.Format : g_D3DSettings.m_D3DFormat;
d3dpp.hDeviceWindow=g_hApplicationWindow;
d3dpp.Windowed=g_D3DSettings.m_bWindowed;
d3dpp.BackBufferCount=1;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
if(g_D3DSettings.m_bMultiSampling)
{
if( SUCCEEDED(g_pD3D->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
d3dpp.BackBufferFormat,
g_D3DSettings.m_bWindowed,
D3DMULTISAMPLE_2_SAMPLES, NULL)))
{
d3dpp.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
}
else
d3dpp.MultiSampleType=D3DMULTISAMPLE_NONE;
}
else
d3dpp.MultiSampleType=D3DMULTISAMPLE_NONE;
d3dpp.EnableAutoDepthStencil=TRUE;
d3dpp.AutoDepthStencilFormat=D3DFMT_D16;
d3dpp.FullScreen_RefreshRateInHz=0;
d3dpp.PresentationInterval = g_D3DSettings.m_bWindowed ? 0 : D3DPRESENT_INTERVAL_IMMEDIATE;
d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
HRESULT rslt=g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hApplicationWindow,
D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDevice);
if(FAILED(rslt))
{
rslt=g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hApplicationWindow,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDevice);
if(FAILED(rslt))
{
return E_FAIL;
}
}
g_D3DSettings.m_PresentParams=d3dpp;
if(g_D3DSettings.m_bWindowed)
g_D3DSettings.m_D3DFormat=d3dpp.BackBufferFormat;
return RestoreDeviceObjects();
}
HRESULT Render()
{
if(!g_pD3DDevice) return E_FAIL;
HRESULT rslt = ValidateDevice();
if(FAILED(rslt)) return rslt;
g_pD3DDevice->Clear(0,0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,55), 0.0f, 0);
rslt = g_pD3DDevice->BeginScene();
if(FAILED(rslt)) return rslt;
g_pD3DDevice->EndScene();
g_pD3DDevice->Present(NULL,NULL,NULL,NULL);
return S_OK;
}
HRESULT ValidateDevice()
{
HRESULT rslt = g_pD3DDevice->TestCooperativeLevel();
if(FAILED(rslt))
{
if(rslt == D3DERR_DEVICELOST)
return E_FAIL;
if(rslt == D3DERR_DEVICENOTRESET)
{
InvalidateDeviceObjects();
g_pD3DDevice->Reset(&g_D3DSettings.m_PresentParams);
RestoreDeviceObjects();
}
}
return S_OK;
}
HRESULT RestoreDeviceObjects()
{
return S_OK;
}
HRESULT InvalidateDeviceObjects()
{
return S_OK;
}
void AppLoop()
{
HRESULT rslt;
rslt = Render();
if(FAILED(rslt)) D3DError(rslt,__LINE__,__FILE__,"Render() Has Failed");
}
void AppShutDown()
{
InvalidateDeviceObjects();
SAFE_RELEASE(g_pD3D);
SAFE_RELEASE(g_pD3DDevice);
}
HRESULT D3DError(HRESULT hrCode, int nLine, char* szFile, char* szExtraInfo)
{
::OutputDebugString("--------------------------D3DError Has Been Called---------------------------\n");
char pszError[256];
wsprintf(pszError, "The following error occurred on line %d of %s\n", nLine, szFile);
::OutputDebugString(pszError);
//::OutputDebugString(DXGetErrorString9(hrCode));
::OutputDebugString("\n");
if(szExtraInfo)
{
::OutputDebugString("Extra information: ");
::OutputDebugString(szExtraInfo);
::OutputDebugString("\n");
}
return hrCode;
}شغله مباشرة في برنامج وندوز لأن المكتبات مرفقة في الكود نفسه باستخدام الموجه Pragma comment
هذا الموضوع مغلق.