Oppure

Loading
10/01/12 15:53
anthony015
Sto cercando di utilizzare un panel all'interno di un form come device per il render direct2d, per il semplice fatto che mi da fastidio dover creare un'altra finestra come ho letto in molti esempi in rete, così, partendo dalla classe DemoApp, che si puo' trovare senza troppa fatica in internet, sto cercando di creare una piccola libreria che permetta di compiere semplici operazioni su un device d2d e dare una semplice possibilità di fare disegni e grafici in un qualsiasi programma.
Funziona tutto correttamente, ma ora che sto cercando di implementare una funzione che mi permetta, come detto inizialmente, di inizializzare il device all'interno di un panel è sorto qualche problema, la classe è la seguente:
(dichiarazioni)
#pragma once
#ifndef WINVER            
#define WINVER 0x0700     
#endif
#ifndef _WIN32_WINNT       
#define _WIN32_WINNT 0x0700 
#endif
#ifndef UNICODE
#define UNICODE
#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <wchar.h>
#include <math.h>
#include <d2d1.h>
#include <d2d1helper.h>
#include <dwrite.h>
#include <wincodec.h>
#include "Lista.h"
#include <iostream>
using namespace std;
template<class Interface>
inline void SafeRelease(
    Interface **ppInterfaceToRelease
    )
{
    if (*ppInterfaceToRelease != NULL)
    {
        (*ppInterfaceToRelease)->Release();

        (*ppInterfaceToRelease) = NULL;
    }
}
#ifndef Assert
#if defined( DEBUG ) || defined( _DEBUG )
#define Assert(b) do {if (!(b)) {OutputDebugStringA("Assert: " #b "\n");}} while(0)
#else
#define Assert(b)
#endif
#ifndef HINST_THISCOMPONENT
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)
#endif
#define HR(_hr_expr) { hr=_hr_expr; if(FAILED(hr)) return hr;}

(classe)
class DemoApp
{
public:
	HWND m_hwnd;
	ID2D1Factory* m_pDirect2dFactory;
	ID2D1HwndRenderTarget* m_pRenderTarget;
	IWICImagingFactory *m_pWICFactory;
	IDWriteFactory *m_pDWriteFactory;
	IDWriteTextFormat *m_pTextFormat;
	ID2D1SolidColorBrush *m_pBlackBrush;
	ID2D1SolidColorBrush* m_pLightSlateGrayBrush;
	ID2D1SolidColorBrush* m_pCornflowerBlueBrush;
	ID2D1SolidColorBrush* pennello;
	float spessoreLinea;
	ID2D1Layer *layer;
	ID2D1Geometry *geometryMask;
public:
	DemoApp() :
	  m_hwnd(NULL),
		  m_pDirect2dFactory(NULL),
		  m_pRenderTarget(NULL),
		  m_pLightSlateGrayBrush(NULL),
		  m_pCornflowerBlueBrush(NULL),
		  pennello(NULL),
		  layer(NULL),
		  geometryMask(NULL)
	  {
		  spessoreLinea=1;
	  }
	  ~DemoApp()
	  {
		  SafeRelease(&m_pDirect2dFactory);
		  SafeRelease(&m_pRenderTarget);
		  SafeRelease(&m_pLightSlateGrayBrush);
		  SafeRelease(&m_pCornflowerBlueBrush);
		  SafeRelease(&pennello);
	  }
	  HRESULT Initialize()
	  {
		  HRESULT hr;
		  hr = CreateDeviceIndependentResources();
		  {
			  // Register the window class.
			  WNDCLASSEX wcex = { sizeof(WNDCLASSEX) };
			  wcex.style         = CS_HREDRAW | CS_VREDRAW;
			  wcex.lpfnWndProc   = DemoApp::WndProc;
			  wcex.cbClsExtra    = 0;
			  wcex.cbWndExtra    = sizeof(LONG_PTR);
			  wcex.hInstance     = HINST_THISCOMPONENT;
			  wcex.hbrBackground = NULL;
			  wcex.lpszMenuName  = NULL;
			  wcex.hCursor       = LoadCursor(NULL, IDI_APPLICATION);
			  wcex.lpszClassName = L"D2DDemoApp";
			  RegisterClassEx(&wcex);
			  FLOAT dpiX, dpiY;
			  m_pDirect2dFactory->GetDesktopDpi(&dpiX, &dpiY);
			  // Create the window.
			  m_hwnd = CreateWindow(
				  L"D2DDemoApp",
				  L"Direct2D",
				  WS_OVERLAPPEDWINDOW,
				  CW_USEDEFAULT,
				  CW_USEDEFAULT,
				  static_cast<UINT>(ceil(640.f * dpiX / 96.f)),
				  static_cast<UINT>(ceil(480.f * dpiY / 96.f)),
				  NULL,
				  NULL,
				  HINST_THISCOMPONENT,
				  this
				  );
			  {
				  ShowWindow(m_hwnd, SW_SHOWNORMAL);
				  UpdateWindow(m_hwnd);
			  }
		  }
		  return hr;
	  }
	  HRESULT Initialize(HWND hwndToBeUsedAsDevice)
	  {
		HRESULT hr;		
		hr = CreateDeviceIndependentResources();
		FLOAT dpiX, dpiY;
		m_pDirect2dFactory->GetDesktopDpi(&dpiX, &dpiY);
		m_hwnd=hwndToBeUsedAsDevice;
		return hr;
	  }
private:
	HRESULT CreateDeviceIndependentResources()
	{
		HRESULT hr = S_OK;
		static const WCHAR msc_fontName[] = L"Verdana";
		static const FLOAT msc_fontSize = 8;
		DWriteCreateFactory(
			DWRITE_FACTORY_TYPE_SHARED,
			__uuidof(m_pDWriteFactory),
			reinterpret_cast<IUnknown **>(&m_pDWriteFactory)
			);
		// Create a Direct2D factory.
		hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pDirect2dFactory);
		m_pTextFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_LEADING);
		m_pTextFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_NEAR);
		return hr;
	}
	HRESULT CreateDeviceResources()
	{
		HRESULT hr = S_OK;

		if (!m_pRenderTarget)
		{
			RECT rc;
			GetClientRect(m_hwnd, &rc);

			D2D1_SIZE_U size = D2D1::SizeU(
				rc.right - rc.left,
				rc.bottom - rc.top
				);
			// Create a Direct2D render target.
			hr = m_pDirect2dFactory->CreateHwndRenderTarget(
				D2D1::RenderTargetProperties(),
				D2D1::HwndRenderTargetProperties(m_hwnd, size),
				&m_pRenderTarget
				);
		}
		m_pRenderTarget->CreateSolidColorBrush(
			D2D1::ColorF(D2D1::ColorF::Black),
			&pennello
			);
		return hr;
	}
	void DiscardDeviceResources()
	{
		SafeRelease(&m_pRenderTarget);
		SafeRelease(&m_pLightSlateGrayBrush);
		SafeRelease(&m_pCornflowerBlueBrush);
	}
	HRESULT OnRender()
	{
		HRESULT hr = S_OK;
		hr = CreateDeviceResources();
		if (SUCCEEDED(hr))
		{
			m_pRenderTarget->BeginDraw();
			m_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
			D2D1_SIZE_F rtSize = m_pRenderTarget->GetSize();
			int width = static_cast<int>(rtSize.width);
			int height = static_cast<int>(rtSize.height);
			hr = m_pRenderTarget->EndDraw();
		}
		if (hr == D2DERR_RECREATE_TARGET)
		{
			hr = S_OK;
			DiscardDeviceResources();
		}
		return hr;
	}
	static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
	{
		LRESULT result = 0;
		if (message == WM_CREATE)
		{
			LPCREATESTRUCT pcs = (LPCREATESTRUCT)lParam;
			DemoApp *pDemoApp = (DemoApp *)pcs->lpCreateParams;
			::SetWindowLongPtrW(
				hwnd,
				GWLP_USERDATA,
				PtrToUlong(pDemoApp)
				);
			result = 1;
		}
		else
		{
			DemoApp *pDemoApp = reinterpret_cast<DemoApp *>(static_cast<LONG_PTR>(
				::GetWindowLongPtrW(
				hwnd,
				GWLP_USERDATA
				)));
			bool wasHandled = false;
			if (pDemoApp)
			{
				switch (message)
				{
				case WM_SIZE:
					{
						UINT width = LOWORD(lParam);
						UINT height = HIWORD(lParam);
						pDemoApp->OnResize(width, height);
					}
					result = 0;
					wasHandled = true;
					break;
				case WM_DISPLAYCHANGE:
					{
						InvalidateRect(hwnd, NULL, FALSE);
					}
					result = 0;
					wasHandled = true;
					break;
				case WM_PAINT:
					{
						pDemoApp->OnRender();
						ValidateRect(hwnd, NULL);
					}
					result = 0;
					wasHandled = true;
					break;
				case WM_DESTROY:
					{
						PostQuitMessage(0);
					}
					result = 1;
					wasHandled = true;
					break;
				}
			}
			if (!wasHandled)
			{
				result = DefWindowProc(hwnd, message, wParam, lParam);
			}
		}
		return result;
	}
public:
	void pulisci()
	{
		m_pRenderTarget->BeginDraw();
		m_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));
		m_pRenderTarget->EndDraw();
	}	
};

Nel form ho messo un pulsante, il quale cliccato mi dovrebbe creare in panel1 il device:
device.Initialize((HWND)panel1->Handle.ToInt32());//device è un istanza di DemoApp

La funzione Initialize() era già nella classe scaricata da Microsoft e lì ho notato che viene creata una finestra e il suo HWND viene usato per renderla un device, così, ho creato la funzione Initialize(HWND HWND hwndToBeUsedAsDevice), che rende m_hwnd=hwndToBeUsedAsDevice, però, al momento di usare una funzione come pulisci(), mi da la NullReferenceException...
Sareste così gentili da chiarirmi dove sbaglio ed eventualmente a trovare soluzioni alternative?
Grazie in anticipo.Assert:
Ultima modifica effettuata da anthony015 10/01/12 15:54
aaa