最近想在MFC中运用D3D,直接来了就用的单文档,结果调试半天还是坐标不对~

鼠标的位置就是y比画的图形要大,而且是越往右下角拉 y 距离相差就越大!!!

但是同样的我用多文档,还有对话框都没有这种问题,请高手赐教@谢谢@

 

为什么多文档,Dialog都没这问题呢?
CODE:

// TestDSIView.cpp : CTestDSIView 类的实现
//

#include 
"stdafx.h"
#include 
"TestDSI.h"

#include 
"TestDSIDoc.h"
#include 
"TestDSIView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CTestDSIView
DWORD CTestDSIView::D3DFVF_CUSTOMVERTEX = (D3DFVF_XYZRHW|D3DFVF_DIFFUSE);
IMPLEMENT_DYNCREATE(CTestDSIView, CView)

BEGIN_MESSAGE_MAP(CTestDSIView, CView)
    
// 标准打印命令
    ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
    ON_WM_LBUTTONDOWN()
    ON_WM_LBUTTONUP()
    ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()

// CTestDSIView 构造/析构

CTestDSIView::CTestDSIView()
{
    
// TODO: 在此处添加构造代码
    m_pD3D = NULL;
    m_pd3dDevice 
= NULL;
    m_pVB 
= NULL;
    m_bEdit 
= false;
}


CTestDSIView::
~CTestDSIView()
{
    
this->Cleanup();
}


BOOL CTestDSIView::PreCreateWindow(CREATESTRUCT
& cs)
{
    
// TODO: 在此处通过修改 CREATESTRUCT cs 来修改窗口类或
    
// 样式

    
return CView::PreCreateWindow(cs);
}


// CTestDSIView 绘制

void CTestDSIView::OnDraw(CDC* /*pDC*/)
{
    CTestDSIDoc
* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    
if (!pDoc)
        
return;

    
// TODO: 在此处为本机数据添加绘制代码
    Render();
}



// CTestDSIView 打印

BOOL CTestDSIView::OnPreparePrinting(CPrintInfo
* pInfo)
{
    
// 默认准备
    return DoPreparePrinting(pInfo);
}


void CTestDSIView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
    
// TODO: 打印前添加额外的初始化
}


void CTestDSIView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
    
// TODO: 打印后添加清除过程
}



// CTestDSIView 诊断

#ifdef _DEBUG
void CTestDSIView::AssertValid() const
{
    CView::AssertValid();
}


void CTestDSIView::Dump(CDumpContext& dc) const
{
    CView::Dump(dc);
}


CTestDSIDoc
* CTestDSIView::GetDocument() const // 非调试版本是内联的
{
    ASSERT(m_pDocument
->IsKindOf(RUNTIME_CLASS(CTestDSIDoc)));
    
return (CTestDSIDoc*)m_pDocument;
}

#endif //_DEBUG

void CTestDSIView::OnInitialUpdate(void)
{
    CView::OnInitialUpdate();

    
this->InitD3D(m_hWnd);
    
//this->InitVB();
}


void CTestDSIView::OnLButtonDown(UINT nFlags, CPoint point)
{
    m_ptDown 
= point;
    m_bEdit 
= true;
    CView::OnLButtonDown(nFlags, point);
}


void CTestDSIView::OnLButtonUp(UINT nFlags, CPoint point)
{
    m_ptUp 
= point;
    m_bEdit 
= false;
    InitVB(m_ptDown.x, m_ptDown.y, point.x, point.y);
    Render();
    CView::OnLButtonUp(nFlags, point);
}


void CTestDSIView::OnMouseMove(UINT nFlags, CPoint point)
{
    
if (m_bEdit)
    
{
        m_ptMove 
= point;
        InitVB(m_ptDown.x, m_ptDown.y, point.x, point.y);
        Render();
    }

    CView::OnMouseMove(nFlags, point);
}



//////////////////////////////////////////////////////////////////////////
// d3d function
HRESULT CTestDSIView::InitD3D( HWND hWnd )
{
    
// Create the D3D object.
    if( NULL == ( m_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
        
return E_FAIL;

    
// Set up the structure used to create the D3DDevice
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory( 
&d3dpp, sizeof(d3dpp) );
    d3dpp.Windowed 
= TRUE;
    d3dpp.SwapEffect 
= D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat 
= D3DFMT_UNKNOWN;

    
// Create the D3DDevice
    if( FAILED( m_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
        D3DCREATE_SOFTWARE_VERTEXPROCESSING,
        
&d3dpp, &m_pd3dDevice ) ) )
    
{
        
return E_FAIL;
    }


    
// Device state would normally be set here

    
return S_OK;
}


HRESULT CTestDSIView::InitVB(
int x1 /* = 0 */int y1 /* = 0 */int x2 /* = 0 */int y2 /* = 0 */)
{
    
// Initialize three vertices for rendering a triangle
    CUSTOMVERTEX vertices[] =
    

        
//{  50.0f, 250.0f, 0.5f, 1.0f, 0xff00ffff, },
        
//      { 50.0f,  50.0f, 0.5f, 1.0f, 0xffff0000, }, // x, y, z, rhw, color
        
//      { 250.0f, 50.0f, 0.5f, 1.0f, 0xff00ff00, },
        
//{ 250.0f, 250.0f, 0.5f, 1.0f, 0xff00ff00, },
        
//{50.0f, 250.0f, 0.5f, 1.0f, 0xff00ffff, },

        
{  x1, y2, 0.f, 0.0f0xff00ffff, },
        
{ x1,  y1, 0.f, 0.0f0xffff0000, }// x, y, z, rhw, color
        { x2, y1, 0.f, 0.0f0xff00ff00, },
        
{ x2, y2, 0.f, 0.0f0xff00ff00, },
        
{x1, y2, 0.f, 0.0f0xff00ffff, },

    }
;

    
// Create the vertex buffer. Here we are allocating enough memory
    
// (from the default pool) to hold all our 3 custom vertices. We also
    
// specify the FVF, so the vertex buffer knows what data it contains.
    if( FAILED( m_pd3dDevice->CreateVertexBuffer(5*sizeof(CUSTOMVERTEX),
        
0, D3DFVF_CUSTOMVERTEX,
        D3DPOOL_DEFAULT, 
&m_pVB, NULL ) ) )
    
{
        
return E_FAIL;
    }


    
// Now we fill the vertex buffer. To do this, we need to Lock() the VB to
    
// gain access to the vertices. This mechanism is required becuase vertex
    
// buffers may be in device memory.
    VOID* pVertices;
    
if( FAILED( m_pVB->Lock( 0sizeof(vertices), (void**)&pVertices, 0 ) ) )
        
return E_FAIL;
    memcpy( pVertices, vertices, 
sizeof(vertices) );
    m_pVB
->Unlock();

    
return S_OK;
}


VOID CTestDSIView::Cleanup()
{
    
if( m_pVB != NULL )        
        m_pVB
->Release();

    
if( m_pd3dDevice != NULL ) 
        m_pd3dDevice
->Release();

    
if( m_pD3D != NULL )       
        m_pD3D
->Release();
}


VOID CTestDSIView::Render()
{
    
// Clear the backbuffer to a blue color
    m_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255), 1.0f0 );

    
// Begin the scene
    if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
    
{
        
// Draw the triangles in the vertex buffer. This is broken into a few
        
// steps. We are passing the vertices down a "stream", so first we need
        
// to specify the source of that stream, which is our vertex buffer. Then
        
// we need to let D3D know what vertex shader to use. Full, custom vertex
        
// shaders are an advanced topic, but in most cases the vertex shader is
        
// just the FVF, so that D3D knows what type of vertices we are dealing
        
// with. Finally, we call DrawPrimitive() which does the actual rendering
        
// of our geometry (in this case, just one triangle).
        m_pd3dDevice->SetStreamSource( 0, m_pVB, 0sizeof(CUSTOMVERTEX) );
        m_pd3dDevice
->SetFVF( D3DFVF_CUSTOMVERTEX );
        m_pd3dDevice
->DrawPrimitive( D3DPT_LINESTRIP, 04 );

        
// End the scene
        m_pd3dDevice->EndScene();
    }


    
// Present the backbuffer contents to the display
    m_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}

//////////////////////////////////////////////////////////////////////////
// CTestDSIView 消息处理程序

 

// TestDSIView.h : CTestDSIView 类的接口
//


#pragma once

#include 
<d3d9.h>
#include 
<d3dx9.h>
#pragma comment(lib, 
"d3d9.lib")
#pragma comment(lib, 
"d3dx9.lib")
#pragma comment(lib, 
"winmm.lib")
#pragma warning(disable : 
4244)

class CTestDSIView : public CView
{
protected// 仅从序列化创建
    CTestDSIView();
    DECLARE_DYNCREATE(CTestDSIView)

// 属性
public:
    CTestDSIDoc
* GetDocument() const;

// 操作
public:

// 重写
    public:
    
virtual void OnDraw(CDC* pDC);  // 重写以绘制该视图
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
    
virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
    
virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
    
virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);

//d3d member
private:
    LPDIRECT3D9                m_pD3D;
    LPDIRECT3DDEVICE9        m_pd3dDevice;
    LPDIRECT3DVERTEXBUFFER9    m_pVB;

    POINT m_ptDown;
    POINT m_ptUp;
    POINT m_ptMove;
    
bool  m_bEdit;
//d3d function member
protected:
    HRESULT InitD3D( HWND hWnd );
    HRESULT InitVB(
int x1 = 0int y1 = 0int x2 = 0int y2 = 0);
    VOID Cleanup();
    VOID Render();
    
    
struct CUSTOMVERTEX
    
{
        FLOAT x, y, z, rhw; 
// The transformed position for the vertex
        DWORD color;        // The vertex color
    }
;

    
// Our custom FVF, which describes our custom vertex structure
    static DWORD D3DFVF_CUSTOMVERTEX;
    
//#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)
// 实现
public:
    
virtual ~CTestDSIView();
#ifdef _DEBUG
    
virtual void AssertValid() const;
    
virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// 生成的消息映射函数
protected:
    DECLARE_MESSAGE_MAP()
    afx_msg 
void OnLButtonDown(UINT nFlags, CPoint point);
    afx_msg 
void OnLButtonUp(UINT nFlags, CPoint point);
    afx_msg 
void OnMouseMove(UINT nFlags, CPoint point);
public:
    
virtual void OnInitialUpdate(void);
}
;

#ifndef _DEBUG  
// TestDSIView.cpp 的调试版本
inline CTestDSIDoc* CTestDSIView::GetDocument() const
   
return reinterpret_cast<CTestDSIDoc*>(m_pDocument); }
#endif


Feedback

# re: 为什么在MFC中的单文档下用D3D画图坐标不对盘!  回复  更多评论   

2008-09-17 13:34 by 小不点
请高手赐教喽!!!!

# re: 为什么在MFC中的单文档下用D3D画图坐标不对盘!  回复  更多评论   

2008-09-19 16:50 by 匿名
我也遇到过这样的问题,创建的800*600的窗口,用getclientrect得到的矩形居然是950*666的,在view视图中用directx也是短一块,就相是说我的鼠标消息坐标是800*600,但是view是950*666的,刚刚发现还没仔细研究,不过这很可能是mfc的问题

# re: 为什么在MFC中的单文档下用D3D画图坐标不对盘!  回复  更多评论   

2008-09-19 19:12 by 小不点
但是 多文档的 只要视图大小不改变 那么就没有偏差,一旦视图大小改变也就又偏差了,
单文档 当一开始 创建,没有添加多的东西的时候(比如左边添加有树控件对话框)那么就只有y坐标又偏差,但是当添加后x,y多有偏差了。
对话框 倒是还好~

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理