Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Utilizzare panel come device Direct2d
Forum - C/C++ - Utilizzare panel come device Direct2d

Avatar
anthony015 (Member)
Pro


Messaggi: 116
Iscritto: 20/05/2011

Segnala al moderatore
Postato alle 16:53
Martedì, 10/01/2012
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)
Codice sorgente - presumibilmente C++

  1. #pragma once
  2. #ifndef WINVER            
  3. #define WINVER 0x0700    
  4. #endif
  5. #ifndef _WIN32_WINNT      
  6. #define _WIN32_WINNT 0x0700
  7. #endif
  8. #ifndef UNICODE
  9. #define UNICODE
  10. #endif
  11. #define WIN32_LEAN_AND_MEAN
  12. #include <windows.h>
  13. #include <stdlib.h>
  14. #include <malloc.h>
  15. #include <memory.h>
  16. #include <wchar.h>
  17. #include <math.h>
  18. #include <d2d1.h>
  19. #include <d2d1helper.h>
  20. #include <dwrite.h>
  21. #include <wincodec.h>
  22. #include "Lista.h"
  23. #include <iostream>
  24. using namespace std;
  25. template<class Interface>
  26. inline void SafeRelease(
  27.     Interface **ppInterfaceToRelease
  28.     )
  29. {
  30.     if (*ppInterfaceToRelease != NULL)
  31.     {
  32.         (*ppInterfaceToRelease)->Release();
  33.  
  34.         (*ppInterfaceToRelease) = NULL;
  35.     }
  36. }
  37. #ifndef Assert
  38. #if defined( DEBUG ) || defined( _DEBUG )
  39. #define Assert(b) do {if (!(b)) {OutputDebugStringA("Assert: " #b "\n");}} while(0)
  40. #else
  41. #define Assert(b)
  42. #endif
  43. #ifndef HINST_THISCOMPONENT
  44. EXTERN_C IMAGE_DOS_HEADER __ImageBase;
  45. #define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)
  46. #endif
  47. #define HR(_hr_expr) { hr=_hr_expr; if(FAILED(hr)) return hr;}


(classe)
Codice sorgente - presumibilmente C/C++

  1. class DemoApp
  2. {
  3. public:
  4.         HWND m_hwnd;
  5.         ID2D1Factory* m_pDirect2dFactory;
  6.         ID2D1HwndRenderTarget* m_pRenderTarget;
  7.         IWICImagingFactory *m_pWICFactory;
  8.         IDWriteFactory *m_pDWriteFactory;
  9.         IDWriteTextFormat *m_pTextFormat;
  10.         ID2D1SolidColorBrush *m_pBlackBrush;
  11.         ID2D1SolidColorBrush* m_pLightSlateGrayBrush;
  12.         ID2D1SolidColorBrush* m_pCornflowerBlueBrush;
  13.         ID2D1SolidColorBrush* pennello;
  14.         float spessoreLinea;
  15.         ID2D1Layer *layer;
  16.         ID2D1Geometry *geometryMask;
  17. public:
  18.         DemoApp() :
  19.           m_hwnd(NULL),
  20.                   m_pDirect2dFactory(NULL),
  21.                   m_pRenderTarget(NULL),
  22.                   m_pLightSlateGrayBrush(NULL),
  23.                   m_pCornflowerBlueBrush(NULL),
  24.                   pennello(NULL),
  25.                   layer(NULL),
  26.                   geometryMask(NULL)
  27.           {
  28.                   spessoreLinea=1;
  29.           }
  30.           ~DemoApp()
  31.           {
  32.                   SafeRelease(&m_pDirect2dFactory);
  33.                   SafeRelease(&m_pRenderTarget);
  34.                   SafeRelease(&m_pLightSlateGrayBrush);
  35.                   SafeRelease(&m_pCornflowerBlueBrush);
  36.                   SafeRelease(&pennello);
  37.           }
  38.           HRESULT Initialize()
  39.           {
  40.                   HRESULT hr;
  41.                   hr = CreateDeviceIndependentResources();
  42.                   {
  43.                           // Register the window class.
  44.                           WNDCLASSEX wcex = { sizeof(WNDCLASSEX) };
  45.                           wcex.style         = CS_HREDRAW | CS_VREDRAW;
  46.                           wcex.lpfnWndProc   = DemoApp::WndProc;
  47.                           wcex.cbClsExtra    = 0;
  48.                           wcex.cbWndExtra    = sizeof(LONG_PTR);
  49.                           wcex.hInstance     = HINST_THISCOMPONENT;
  50.                           wcex.hbrBackground = NULL;
  51.                           wcex.lpszMenuName  = NULL;
  52.                           wcex.hCursor       = LoadCursor(NULL, IDI_APPLICATION);
  53.                           wcex.lpszClassName = L"D2DDemoApp";
  54.                           RegisterClassEx(&wcex);
  55.                           FLOAT dpiX, dpiY;
  56.                           m_pDirect2dFactory->GetDesktopDpi(&dpiX, &dpiY);
  57.                           // Create the window.
  58.                           m_hwnd = CreateWindow(
  59.                                   L"D2DDemoApp",
  60.                                   L"Direct2D",
  61.                                   WS_OVERLAPPEDWINDOW,
  62.                                   CW_USEDEFAULT,
  63.                                   CW_USEDEFAULT,
  64.                                   static_cast<UINT>(ceil(640.f * dpiX / 96.f)),
  65.                                   static_cast<UINT>(ceil(480.f * dpiY / 96.f)),
  66.                                   NULL,
  67.                                   NULL,
  68.                                   HINST_THISCOMPONENT,
  69.                                   this
  70.                                   );
  71.                           {
  72.                                   ShowWindow(m_hwnd, SW_SHOWNORMAL);
  73.                                   UpdateWindow(m_hwnd);
  74.                           }
  75.                   }
  76.                   return hr;
  77.           }
  78.           HRESULT Initialize(HWND hwndToBeUsedAsDevice)
  79.           {
  80.                 HRESULT hr;            
  81.                 hr = CreateDeviceIndependentResources();
  82.                 FLOAT dpiX, dpiY;
  83.                 m_pDirect2dFactory->GetDesktopDpi(&dpiX, &dpiY);
  84.                 m_hwnd=hwndToBeUsedAsDevice;
  85.                 return hr;
  86.           }
  87. private:
  88.         HRESULT CreateDeviceIndependentResources()
  89.         {
  90.                 HRESULT hr = S_OK;
  91.                 static const WCHAR msc_fontName[] = L"Verdana";
  92.                 static const FLOAT msc_fontSize = 8;
  93.                 DWriteCreateFactory(
  94.                         DWRITE_FACTORY_TYPE_SHARED,
  95.                         __uuidof(m_pDWriteFactory),
  96.                         reinterpret_cast<IUnknown **>(&m_pDWriteFactory)
  97.                         );
  98.                 // Create a Direct2D factory.
  99.                 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pDirect2dFactory);
  100.                 m_pTextFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_LEADING);
  101.                 m_pTextFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_NEAR);
  102.                 return hr;
  103.         }
  104.         HRESULT CreateDeviceResources()
  105.         {
  106.                 HRESULT hr = S_OK;
  107.  
  108.                 if (!m_pRenderTarget)
  109.                 {
  110.                         RECT rc;
  111.                         GetClientRect(m_hwnd, &rc);
  112.  
  113.                         D2D1_SIZE_U size = D2D1::SizeU(
  114.                                 rc.right - rc.left,
  115.                                 rc.bottom - rc.top
  116.                                 );
  117.                         // Create a Direct2D render target.
  118.                         hr = m_pDirect2dFactory->CreateHwndRenderTarget(
  119.                                 D2D1::RenderTargetProperties(),
  120.                                 D2D1::HwndRenderTargetProperties(m_hwnd, size),
  121.                                 &m_pRenderTarget
  122.                                 );
  123.                 }
  124.                 m_pRenderTarget->CreateSolidColorBrush(
  125.                         D2D1::ColorF(D2D1::ColorF::Black),
  126.                         &pennello
  127.                         );
  128.                 return hr;
  129.         }
  130.         void DiscardDeviceResources()
  131.         {
  132.                 SafeRelease(&m_pRenderTarget);
  133.                 SafeRelease(&m_pLightSlateGrayBrush);
  134.                 SafeRelease(&m_pCornflowerBlueBrush);
  135.         }
  136.         HRESULT OnRender()
  137.         {
  138.                 HRESULT hr = S_OK;
  139.                 hr = CreateDeviceResources();
  140.                 if (SUCCEEDED(hr))
  141.                 {
  142.                         m_pRenderTarget->BeginDraw();
  143.                         m_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
  144.                         D2D1_SIZE_F rtSize = m_pRenderTarget->GetSize();
  145.                         int width = static_cast<int>(rtSize.width);
  146.                         int height = static_cast<int>(rtSize.height);
  147.                         hr = m_pRenderTarget->EndDraw();
  148.                 }
  149.                 if (hr == D2DERR_RECREATE_TARGET)
  150.                 {
  151.                         hr = S_OK;
  152.                         DiscardDeviceResources();
  153.                 }
  154.                 return hr;
  155.         }
  156.         static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  157.         {
  158.                 LRESULT result = 0;
  159.                 if (message == WM_CREATE)
  160.                 {
  161.                         LPCREATESTRUCT pcs = (LPCREATESTRUCT)lParam;
  162.                         DemoApp *pDemoApp = (DemoApp *)pcs->lpCreateParams;
  163.                         ::SetWindowLongPtrW(
  164.                                 hwnd,
  165.                                 GWLP_USERDATA,
  166.                                 PtrToUlong(pDemoApp)
  167.                                 );
  168.                         result = 1;
  169.                 }
  170.                 else
  171.                 {
  172.                         DemoApp *pDemoApp = reinterpret_cast<DemoApp *>(static_cast<LONG_PTR>(
  173.                                 ::GetWindowLongPtrW(
  174.                                 hwnd,
  175.                                 GWLP_USERDATA
  176.                                 )));
  177.                         bool wasHandled = false;
  178.                         if (pDemoApp)
  179.                         {
  180.                                 switch (message)
  181.                                 {
  182.                                 case WM_SIZE:
  183.                                         {
  184.                                                 UINT width = LOWORD(lParam);
  185.                                                 UINT height = HIWORD(lParam);
  186.                                                 pDemoApp->OnResize(width, height);
  187.                                         }
  188.                                         result = 0;
  189.                                         wasHandled = true;
  190.                                         break;
  191.                                 case WM_DISPLAYCHANGE:
  192.                                         {
  193.                                                 InvalidateRect(hwnd, NULL, FALSE);
  194.                                         }
  195.                                         result = 0;
  196.                                         wasHandled = true;
  197.                                         break;
  198.                                 case WM_PAINT:
  199.                                         {
  200.                                                 pDemoApp->OnRender();
  201.                                                 ValidateRect(hwnd, NULL);
  202.                                         }
  203.                                         result = 0;
  204.                                         wasHandled = true;
  205.                                         break;
  206.                                 case WM_DESTROY:
  207.                                         {
  208.                                                 PostQuitMessage(0);
  209.                                         }
  210.                                         result = 1;
  211.                                         wasHandled = true;
  212.                                         break;
  213.                                 }
  214.                         }
  215.                         if (!wasHandled)
  216.                         {
  217.                                 result = DefWindowProc(hwnd, message, wParam, lParam);
  218.                         }
  219.                 }
  220.                 return result;
  221.         }
  222. public:
  223.         void pulisci()
  224.         {
  225.                 m_pRenderTarget->BeginDraw();
  226.                 m_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));
  227.                 m_pRenderTarget->EndDraw();
  228.         }      
  229. };


Nel form ho messo un pulsante, il quale cliccato mi dovrebbe creare in panel1 il device:
Codice sorgente - presumibilmente Plain Text

  1. 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 il 10/01/2012 alle 16:54
PM Quote