<p>I did not set Loaded=&quot;Window_Loaded&quot; in</p>
<pre><code>&lt;Window x:Class=&quot;OpenGLinWPF.OpenGLHWND&quot;
        xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
        xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
        xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
        xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
        xmlns:local=&quot;clr-namespace:OpenGLinWPF&quot;
        mc:Ignorable=&quot;d&quot;
        Title=&quot;OpenGLHWND&quot; Height=&quot;450&quot; Width=&quot;800&quot;
        Loaded=&quot;Window_Loaded&quot;&gt;
    &lt;Grid&gt;
        &lt;Border Name=&quot;hwndPlaceholder&quot; /&gt;
    &lt;/Grid&gt;
&lt;/Window&gt;
</code></pre>
<p>The description of the Window.Loaded event here says</p>
<blockquote>
<p>Occurs when the element is laid out, rendered, and ready for
interaction.</p>
</blockquote>
<p>After setting it I get:</p>
<p><a href="https://i.sstatic.net/49Ooj.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/49Ooj.png" alt="enter image description here" /></a></p>

CC BY-SA 4.0
2022-06-20T17:02:42.087Z
2022-06-20T17:14:27.417Z
2022-06-20T17:14:27.417Z
Arjan Singh
<p>I am following this <a href="https://www.codeproject.com/Articles/23736/Creating-OpenGL-Windows-in-WPF" rel="nofollow noreferrer">tutorial</a> on how to host Win32 OpenGL windows in WPF. There is also a Microsoft walkthrough on how to <a href="https://docs.microsoft.com/en-us/dotnet/desktop/wpf/advanced/walkthrough-hosting-a-win32-control-in-wpf?view=netframeworkdesktop-4.8" rel="nofollow noreferrer">Host a Win32 Control in WPF</a> that is useful aswell. The original project is from 2009 and uses managed C++ but doesn't actually render. I have rebuilt the program using the same source code (a few modifications due to debugging) using a C++ CLR Class Library. I use the compiled DLL in C# WPF however, when I run the program I get a blank window as opposed to the triangle in the tutorial.</p>
<p>I was wondering if someone could take a look at my program and see why nothing is rendering.</p>
<p>What the original program renders:</p>
<p><a href="https://i.sstatic.net/FAd3o.jpg" rel="nofollow noreferrer"><img src="https://i.sstatic.net/FAd3o.jpg" alt="enter image description here" /></a></p>
<p>What I am getting:</p>
<p><a href="https://i.sstatic.net/tp3tP.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/tp3tP.png" alt="enter image description here" /></a></p>
<p>Here is a <a href="https://github.com/arjansingh00/OpenGLinWPF" rel="nofollow noreferrer">link</a> to the source on GitHub.</p>
<p>OpenGLCpp.h</p>
<pre><code>#pragma once

// Exclude rarely used parts of the windows headers
#define WIN32_LEAN_AND_MEAN

#include &lt;Windows.h&gt;

#include &quot;Helper.h&quot;
#include &quot;OpenGL.h&quot;

// To use these, we must add some references...
//  o PresentationFramework (for HwndHost)
//      * PresentationCore
//      * WindowsBase
using namespace System;
using namespace System::Windows;
using namespace System::Windows::Interop;
using namespace System::Windows::Input;
using namespace System::Windows::Media;
using namespace System::Runtime::InteropServices;

namespace OpenGLCpp 
{
    LRESULT WINAPI MyMsgProc(HWND _hWnd, UINT _msg, WPARAM _wParam, LPARAM _lParam)
    {
        switch (_msg)
        {
            // Make sure the window gets focus when it has to!
        case WM_IME_SETCONTEXT:
            // LOWORD(wParam) = 0 stands for deactivation, so don't set
            // focus then (results in a rather, err... 'greedy' window...)
            if (LOWORD(_wParam) &gt; 0)
                SetFocus(_hWnd);

            return 0;

        default:
            return DefWindowProc(_hWnd, _msg, _wParam, _lParam);
        }
    }

    //
    // This class implements HwndHost
    //
    // We have to overwrite BuildWindowCore and DestroyWindowCore
    //
    // A very simple example which creates a Win32 ListBox can be found in the MSDN:
    // http://msdn2.microsoft.com/en-us/library/aa970061.aspx
    //
    public ref class OpenGLHwnd : public HwndHost
    {
    public:
        OpenGLHwnd() : m_hRC(NULL),
            m_hDC(NULL),
            m_hWnd(NULL),
            m_hInstance(NULL),
            m_sWindowName(NULL),
            m_sClassName(NULL),
            m_fRotationAngle(0.0f)
        {
        }

    private:
        HGLRC                   m_hRC;
        HDC                     m_hDC;
        HWND                    m_hWnd;
        HINSTANCE               m_hInstance;
        LPCWSTR                 m_sWindowName;
        LPCWSTR                 m_sClassName;

        float                   m_fRotationAngle;

        // DPI Scaling
        double                  m_dScaleX;
        double                  m_dScaleY;

    protected:
        /*virtual IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, bool% handled) override
        {
            switch( msg )
            {
                case WM_IME_SETCONTEXT:
                    if(LOWORD(wParam.ToInt32()) &gt; 0)
                        SetFocus(m_hWnd);

                    handled = true;
                    return System::IntPtr::Zero;
            }

            handled = false;
            return System::IntPtr::Zero;
        }*/
    public:
        virtual void OnRenderSizeChanged(SizeChangedInfo^ sizeInfo) override
        {
            if (m_hDC == NULL || m_hRC == NULL)
                return;

            // Apply DPI correction
            // NOTE: sizeInfo-&gt;NewSize contains doubles, so we do the multiplication before
            // converting to int.
            int iHeight = (int)(sizeInfo-&gt;NewSize.Height * m_dScaleY);
            int iWidth = (int)(sizeInfo-&gt;NewSize.Width * m_dScaleX);

            if (iWidth == 0 || iHeight == 0)
                return;

            wglMakeCurrent(m_hDC, m_hRC);
            glViewport(0, 0, iWidth, iHeight);

            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
            glOrtho(-1.0, 1.0, -1.0, 1.0, 1.0, 100.0);
            // gluPerspective( 67.5, ((double)(iWidth) / (double)(iHeight)), 1.0, 500.0);
            glMatrixMode(GL_MODELVIEW);
            glLoadIdentity();
        }

        //
        // Communicating with this method will be considerably more complicated in a real-
        // world application...
        //
        virtual void OnRender(System::Windows::Media::DrawingContext^ drawingContext) override
        {
            UNREF(drawingContext);

            if (m_hDC == NULL || m_hRC == NULL)
                return;

            wglMakeCurrent(m_hDC, m_hRC);

            glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            glLoadIdentity();

            glTranslatef(0.0f, 0.0f, -2.6f);
            glRotatef(m_fRotationAngle, 0.0f, 1.0f, 0.0f);

            glBegin(GL_TRIANGLES);
            glColor3f(1.0f, 0.0f, 0.0f);    glVertex3f(-1.0f, -1.0f, 0.0f);
            glColor3f(0.0f, 1.0f, 0.0f);    glVertex3f(0.0f, 1.0f, 0.0f);
            glColor3f(0.0f, 0.0f, 1.0f);    glVertex3f(1.0f, -1.0f, 0.0f);
            glEnd();

            glFlush();
            SwapBuffers(m_hDC); // NOTE: This is no longer wglSwapBuffers

            // For constant rotation speed, and correct rotation speeds on different machines,
            // we'd need a timer here. However, I don't want to bloat the example code.
            m_fRotationAngle += 1.0;
        }

        virtual void DestroyWindowCore(HandleRef hwnd) override
        {
            if (NULL != m_hRC)
            {
                wglDeleteContext(m_hRC);
                m_hRC = NULL;
            }

            if (NULL != m_hWnd &amp;&amp; NULL != m_hDC)
            {
                ReleaseDC(m_hWnd, m_hDC);
                m_hDC = NULL;
            }

            if (NULL != m_hWnd &amp;&amp; m_hWnd == (HWND)hwnd.Handle.ToPointer())
            {
                ::DestroyWindow(m_hWnd);
                m_hWnd = NULL;
            }

            UnregisterClass(m_sClassName, m_hInstance);
        }

        //Allowing Multiple Instances of the Window
        bool RegisterWindowClass()
        {
            //
            // Create custom WNDCLASS
            //
            WNDCLASS wndClass;

            if (GetClassInfo(m_hInstance, m_sClassName, &amp;wndClass))
            {
                // Class is already registered!
                return true;
            }

            wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;

            // Not providing a WNDPROC here results in a crash on my system:
            wndClass.lpfnWndProc = (WNDPROC)MyMsgProc;
            wndClass.cbClsExtra = 0;
            wndClass.cbWndExtra = 0;
            wndClass.hInstance = m_hInstance;
            wndClass.hIcon = LoadIcon(NULL, IDI_WINLOGO);
            wndClass.hCursor = LoadCursor(0, IDC_ARROW);
            wndClass.hbrBackground = 0;
            wndClass.lpszMenuName = 0; // No menu
            wndClass.lpszClassName = m_sClassName;

            // ... and register it
            if (!RegisterClass(&amp;wndClass))
            {
                Helper::ErrorExit(L&quot;RegisterWindowClass&quot;);
                return false;
            }

            return true;
        }

        //
        // This is the key method to override
        //
        virtual HandleRef BuildWindowCore(HandleRef hwndParent) override
        {
            // Get HINSTANCE
            m_hInstance = (HINSTANCE)GetModuleHandle(NULL);
            m_sWindowName = L&quot;OpenGL in HwndHost&quot;;
            m_sClassName = L&quot;OGLClassHwnd&quot;;

            if (RegisterWindowClass())
            {
                // some default size
                int iWidth = 2;
                int iHeight = 2;

                DWORD dwStyle = WS_CHILD | WS_VISIBLE;

                // Get the parent (WPF) Hwnd. This is important: Windows won't let you create
                // the Hwnd otherwise.
                HWND parentHwnd = (HWND)hwndParent.Handle.ToPointer();

                m_hWnd = CreateWindowEx(0,
                    m_sClassName,
                    m_sWindowName,
                    dwStyle,
                    0,  // X Pos
                    0,  // Y Pos
                    iWidth,
                    iHeight,
                    parentHwnd, // Parent
                    0,  // Menu
                    m_hInstance,
                    0); // Param

                if (!m_hWnd)
                {
                    Helper::ErrorExit(L&quot;BuildWindowCore&quot;);
                }

                m_hDC = GetDC(m_hWnd);
                if (!m_hDC)
                {
                    Helper::ErrorExit(L&quot;BuildWindowCore&quot;);
                }

                //
                // Create PixelFormatDescriptor and choose pixel format
                //
                uint PixelFormat;

                BYTE iAlphaBits = 0;
                BYTE iColorBits = 32;
                BYTE iDepthBits = 16;
                BYTE iAccumBits = 0;
                BYTE iStencilBits = 0;

                static PIXELFORMATDESCRIPTOR pfd =
                {
                    sizeof(PIXELFORMATDESCRIPTOR),  //size
                    1,                              //version
                    PFD_DRAW_TO_WINDOW |                //flags
                    PFD_SUPPORT_OPENGL |
                    PFD_DOUBLEBUFFER,
                    PFD_TYPE_RGBA,                  //pixeltype
                    iColorBits,
                    0, 0, 0, 0, 0, 0,               //color bits ignored
                    iAlphaBits,
                    0,                              //alpha shift ignored
                    iAccumBits,                     //accum. buffer
                    0, 0, 0, 0,                     //accum bits ignored
                    iDepthBits,                     //depth buffer
                    iStencilBits,                   //stencil buffer
                    0,                              //aux buffer
                    PFD_MAIN_PLANE,                 //layer type
                    0,                              //reserved
                    0, 0, 0                         //masks ignored
                };

                PixelFormat = ChoosePixelFormat(m_hDC, &amp;pfd);
                if (!PixelFormat)
                {
                    Helper::ErrorExit(L&quot;BuildWindowCore&quot;);
                }

                if (!SetPixelFormat(m_hDC, PixelFormat, &amp;pfd))
                {
                    Helper::ErrorExit(L&quot;BuildWindowCore&quot;);
                }

                m_hRC = wglCreateContext(m_hDC);
                if (!m_hRC)
                {
                    Helper::ErrorExit(L&quot;BuildWindowCore&quot;);
                }

                if (!wglMakeCurrent(m_hDC, m_hRC))
                {
                    Helper::ErrorExit(L&quot;BuildWindowCore&quot;);
                }

                //
                // Get DPI information and store scaling relative to 96 DPI.
                // See http://msdn2.microsoft.com/en-us/library/ms969894.aspx
                //
                m_dScaleX = GetDeviceCaps(m_hDC, LOGPIXELSX) / 96.0;
                m_dScaleY = GetDeviceCaps(m_hDC, LOGPIXELSY) / 96.0;

                glEnable(GL_DEPTH_TEST);
                glDisable(GL_TEXTURE_2D);

                return HandleRef(this, IntPtr(m_hWnd));
            }

            return HandleRef(nullptr, System::IntPtr::Zero);
        }
    };
}
</code></pre>
<p>OpenGLHWND.xaml.cs</p>
<pre><code>using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

using System.Windows.Interop; //HwndHost
using OpenGLCpp;

namespace OpenGLinWPF
{
    /// &lt;summary&gt;
    /// Interaction logic for OpenGLHWND.xaml
    /// &lt;/summary&gt;
    public partial class OpenGLHWND : Window
    {
        public OpenGLHWND()
        {
            InitializeComponent();
        }

        private System.Windows.Threading.DispatcherTimer updateTimer = new System.Windows.Threading.DispatcherTimer();

        public override void BeginInit()
        {
            updateTimer.Interval = new TimeSpan(160000);
            updateTimer.Tick += new EventHandler(updateTimer_Tick);
            updateTimer.Start();
            base.BeginInit();
        }

        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            base.OnClosing(e);

            if (!e.Cancel)
            {
                if (null != updateTimer)
                {
                    updateTimer.Stop();
                    updateTimer = null;
                }
            }
        }

        private void updateTimer_Tick(object sender, EventArgs e)
        {
            if (null != hwndPlaceholder &amp;&amp;
                null != hwndPlaceholder.Child)
            {
                hwndPlaceholder.Child.InvalidateVisual();
            }
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            // Create our OpenGL Hwnd 'control'...
            HwndHost host = new OpenGLCpp.OpenGLHwnd(); 

            // ... and attach it to the placeholder control:
            hwndPlaceholder.Child = host;
        }

    }
}
</code></pre>

<opengl><c++><c#>
Hosting OpenGL C++ Window in C# WPF
Arjan Singh
# Hosting OpenGL C++ Window in C# WPF

(Asked by: username_0 on 2022-06-19)

I am following this [tutorial](https://www.codeproject.com/Articles/23736/Creating-OpenGL-Windows-in-WPF) on how to host Win32 OpenGL windows in WPF. There is also a Microsoft walkthrough on how to [Host a Win32 Control in WPF](https://docs.microsoft.com/en-us/dotnet/desktop/wpf/advanced/walkthrough-hosting-a-win32-control-in-wpf?view=netframeworkdesktop-4.8) that is useful aswell. The original project is from 2009 and uses managed C++ but doesn't actually render. I have rebuilt the program using the same source code (a few modifications due to debugging) using a C++ CLR Class Library. I use the compiled DLL in C# WPF however, when I run the program I get a blank window as opposed to the triangle in the tutorial.

I was wondering if someone could take a look at my program and see why nothing is rendering.

What the original program renders:

[![enter image description here](https://i.sstatic.net/FAd3o.jpg)](https://i.sstatic.net/FAd3o.jpg)

What I am getting:

[![enter image description here](https://i.sstatic.net/tp3tP.png)](https://i.sstatic.net/tp3tP.png)

Here is a [link](https://github.com/arjansingh00/OpenGLinWPF) to the source on GitHub.

OpenGLCpp.h

```
#pragma once

// Exclude rarely used parts of the windows headers
#define WIN32_LEAN_AND_MEAN

#include <Windows.h>

#include "Helper.h"
#include "OpenGL.h"

// To use these, we must add some references...
//  o PresentationFramework (for HwndHost)
//      * PresentationCore
//      * WindowsBase
using namespace System;
using namespace System::Windows;
using namespace System::Windows::Interop;
using namespace System::Windows::Input;
using namespace System::Windows::Media;
using namespace System::Runtime::InteropServices;

namespace OpenGLCpp 
{
    LRESULT WINAPI MyMsgProc(HWND _hWnd, UINT _msg, WPARAM _wParam, LPARAM _lParam)
    {
        switch (_msg)
        {
            // Make sure the window gets focus when it has to!
        case WM_IME_SETCONTEXT:
            // LOWORD(wParam) = 0 stands for deactivation, so don't set
            // focus then (results in a rather, err... 'greedy' window...)
            if (LOWORD(_wParam) > 0)
                SetFocus(_hWnd);

            return 0;

        default:
            return DefWindowProc(_hWnd, _msg, _wParam, _lParam);
        }
    }

    //
    // This class implements HwndHost
    //
    // We have to overwrite BuildWindowCore and DestroyWindowCore
    //
    // A very simple example which creates a Win32 ListBox can be found in the MSDN:
    // http://msdn2.microsoft.com/en-us/library/aa970061.aspx
    //
    public ref class OpenGLHwnd : public HwndHost
    {
    public:
        OpenGLHwnd() : m_hRC(NULL),
            m_hDC(NULL),
            m_hWnd(NULL),
            m_hInstance(NULL),
            m_sWindowName(NULL),
            m_sClassName(NULL),
            m_fRotationAngle(0.0f)
        {
        }

    private:
        HGLRC                   m_hRC;
        HDC                     m_hDC;
        HWND                    m_hWnd;
        HINSTANCE               m_hInstance;
        LPCWSTR                 m_sWindowName;
        LPCWSTR                 m_sClassName;

        float                   m_fRotationAngle;

        // DPI Scaling
        double                  m_dScaleX;
        double                  m_dScaleY;

    protected:
        /*virtual IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, bool% handled) override
        {
            switch( msg )
            {
                case WM_IME_SETCONTEXT:
                    if(LOWORD(wParam.ToInt32()) > 0)
                        SetFocus(m_hWnd);

                    handled = true;
                    return System::IntPtr::Zero;
            }

            handled = false;
            return System::IntPtr::Zero;
        }*/
    public:
        virtual void OnRenderSizeChanged(SizeChangedInfo^ sizeInfo) override
        {
            if (m_hDC == NULL || m_hRC == NULL)
                return;

            // Apply DPI correction
            // NOTE: sizeInfo->NewSize contains doubles, so we do the multiplication before
            // converting to int.
            int iHeight = (int)(sizeInfo->NewSize.Height * m_dScaleY);
            int iWidth = (int)(sizeInfo->NewSize.Width * m_dScaleX);

            if (iWidth == 0 || iHeight == 0)
                return;

            wglMakeCurrent(m_hDC, m_hRC);
            glViewport(0, 0, iWidth, iHeight);

            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
            glOrtho(-1.0, 1.0, -1.0, 1.0, 1.0, 100.0);
            // gluPerspective( 67.5, ((double)(iWidth) / (double)(iHeight)), 1.0, 500.0);
            glMatrixMode(GL_MODELVIEW);
            glLoadIdentity();
        }

        //
        // Communicating with this method will be considerably more complicated in a real-
        // world application...
        //
        virtual void OnRender(System::Windows::Media::DrawingContext^ drawingContext) override
        {
            UNREF(drawingContext);

            if (m_hDC == NULL || m_hRC == NULL)
                return;

            wglMakeCurrent(m_hDC, m_hRC);

            glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            glLoadIdentity();

            glTranslatef(0.0f, 0.0f, -2.6f);
            glRotatef(m_fRotationAngle, 0.0f, 1.0f, 0.0f);

            glBegin(GL_TRIANGLES);
            glColor3f(1.0f, 0.0f, 0.0f);    glVertex3f(-1.0f, -1.0f, 0.0f);
            glColor3f(0.0f, 1.0f, 0.0f);    glVertex3f(0.0f, 1.0f, 0.0f);
            glColor3f(0.0f, 0.0f, 1.0f);    glVertex3f(1.0f, -1.0f, 0.0f);
            glEnd();

            glFlush();
            SwapBuffers(m_hDC); // NOTE: This is no longer wglSwapBuffers

            // For constant rotation speed, and correct rotation speeds on different machines,
            // we'd need a timer here. However, I don't want to bloat the example code.
            m_fRotationAngle += 1.0;
        }

        virtual void DestroyWindowCore(HandleRef hwnd) override
        {
            if (NULL != m_hRC)
            {
                wglDeleteContext(m_hRC);
                m_hRC = NULL;
            }

            if (NULL != m_hWnd && NULL != m_hDC)
            {
                ReleaseDC(m_hWnd, m_hDC);
                m_hDC = NULL;
            }

            if (NULL != m_hWnd && m_hWnd == (HWND)hwnd.Handle.ToPointer())
            {
                ::DestroyWindow(m_hWnd);
                m_hWnd = NULL;
            }

            UnregisterClass(m_sClassName, m_hInstance);
        }

        //Allowing Multiple Instances of the Window
        bool RegisterWindowClass()
        {
            //
            // Create custom WNDCLASS
            //
            WNDCLASS wndClass;

            if (GetClassInfo(m_hInstance, m_sClassName, &wndClass))
            {
                // Class is already registered!
                return true;
            }

            wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;

            // Not providing a WNDPROC here results in a crash on my system:
            wndClass.lpfnWndProc = (WNDPROC)MyMsgProc;
            wndClass.cbClsExtra = 0;
            wndClass.cbWndExtra = 0;
            wndClass.hInstance = m_hInstance;
            wndClass.hIcon = LoadIcon(NULL, IDI_WINLOGO);
            wndClass.hCursor = LoadCursor(0, IDC_ARROW);
            wndClass.hbrBackground = 0;
            wndClass.lpszMenuName = 0; // No menu
            wndClass.lpszClassName = m_sClassName;

            // ... and register it
            if (!RegisterClass(&wndClass))
            {
                Helper::ErrorExit(L"RegisterWindowClass");
                return false;
            }

            return true;
        }

        //
        // This is the key method to override
        //
        virtual HandleRef BuildWindowCore(HandleRef hwndParent) override
        {
            // Get HINSTANCE
            m_hInstance = (HINSTANCE)GetModuleHandle(NULL);
            m_sWindowName = L"OpenGL in HwndHost";
            m_sClassName = L"OGLClassHwnd";

            if (RegisterWindowClass())
            {
                // some default size
                int iWidth = 2;
                int iHeight = 2;

                DWORD dwStyle = WS_CHILD | WS_VISIBLE;

                // Get the parent (WPF) Hwnd. This is important: Windows won't let you create
                // the Hwnd otherwise.
                HWND parentHwnd = (HWND)hwndParent.Handle.ToPointer();

                m_hWnd = CreateWindowEx(0,
                    m_sClassName,
                    m_sWindowName,
                    dwStyle,
                    0,  // X Pos
                    0,  // Y Pos
                    iWidth,
                    iHeight,
                    parentHwnd, // Parent
                    0,  // Menu
                    m_hInstance,
                    0); // Param

                if (!m_hWnd)
                {
                    Helper::ErrorExit(L"BuildWindowCore");
                }

                m_hDC = GetDC(m_hWnd);
                if (!m_hDC)
                {
                    Helper::ErrorExit(L"BuildWindowCore");
                }

                //
                // Create PixelFormatDescriptor and choose pixel format
                //
                uint PixelFormat;

                BYTE iAlphaBits = 0;
                BYTE iColorBits = 32;
                BYTE iDepthBits = 16;
                BYTE iAccumBits = 0;
                BYTE iStencilBits = 0;

                static PIXELFORMATDESCRIPTOR pfd =
                {
                    sizeof(PIXELFORMATDESCRIPTOR),  //size
                    1,                              //version
                    PFD_DRAW_TO_WINDOW |                //flags
                    PFD_SUPPORT_OPENGL |
                    PFD_DOUBLEBUFFER,
                    PFD_TYPE_RGBA,                  //pixeltype
                    iColorBits,
                    0, 0, 0, 0, 0, 0,               //color bits ignored
                    iAlphaBits,
                    0,                              //alpha shift ignored
                    iAccumBits,                     //accum. buffer
                    0, 0, 0, 0,                     //accum bits ignored
                    iDepthBits,                     //depth buffer
                    iStencilBits,                   //stencil buffer
                    0,                              //aux buffer
                    PFD_MAIN_PLANE,                 //layer type
                    0,                              //reserved
                    0, 0, 0                         //masks ignored
                };

                PixelFormat = ChoosePixelFormat(m_hDC, &pfd);
                if (!PixelFormat)
                {
                    Helper::ErrorExit(L"BuildWindowCore");
                }

                if (!SetPixelFormat(m_hDC, PixelFormat, &pfd))
                {
                    Helper::ErrorExit(L"BuildWindowCore");
                }

                m_hRC = wglCreateContext(m_hDC);
                if (!m_hRC)
                {
                    Helper::ErrorExit(L"BuildWindowCore");
                }

                if (!wglMakeCurrent(m_hDC, m_hRC))
                {
                    Helper::ErrorExit(L"BuildWindowCore");
                }

                //
                // Get DPI information and store scaling relative to 96 DPI.
                // See http://msdn2.microsoft.com/en-us/library/ms969894.aspx
                //
                m_dScaleX = GetDeviceCaps(m_hDC, LOGPIXELSX) / 96.0;
                m_dScaleY = GetDeviceCaps(m_hDC, LOGPIXELSY) / 96.0;

                glEnable(GL_DEPTH_TEST);
                glDisable(GL_TEXTURE_2D);

                return HandleRef(this, IntPtr(m_hWnd));
            }

            return HandleRef(nullptr, System::IntPtr::Zero);
        }
    };
}

```

OpenGLHWND.xaml.cs

```
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

using System.Windows.Interop; //HwndHost
using OpenGLCpp;

namespace OpenGLinWPF
{
    /// <summary>
    /// Interaction logic for OpenGLHWND.xaml
    /// </summary>
    public partial class OpenGLHWND : Window
    {
        public OpenGLHWND()
        {
            InitializeComponent();
        }

        private System.Windows.Threading.DispatcherTimer updateTimer = new System.Windows.Threading.DispatcherTimer();

        public override void BeginInit()
        {
            updateTimer.Interval = new TimeSpan(160000);
            updateTimer.Tick += new EventHandler(updateTimer_Tick);
            updateTimer.Start();
            base.BeginInit();
        }

        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            base.OnClosing(e);

            if (!e.Cancel)
            {
                if (null != updateTimer)
                {
                    updateTimer.Stop();
                    updateTimer = null;
                }
            }
        }

        private void updateTimer_Tick(object sender, EventArgs e)
        {
            if (null != hwndPlaceholder &&
                null != hwndPlaceholder.Child)
            {
                hwndPlaceholder.Child.InvalidateVisual();
            }
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            // Create our OpenGL Hwnd 'control'...
            HwndHost host = new OpenGLCpp.OpenGLHwnd(); 

            // ... and attach it to the placeholder control:
            hwndPlaceholder.Child = host;
        }

    }
}

```

**Tags:** opengl, c++, c#


---

## 1 answers

### Answer by username_0 on 2022-06-20. Score: 0 | Accepted answer

I did not set Loaded="Window\_Loaded" in

```
<Window x:Class="OpenGLinWPF.OpenGLHWND"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:OpenGLinWPF"
        mc:Ignorable="d"
        Title="OpenGLHWND" Height="450" Width="800"
        Loaded="Window_Loaded">
    <Grid>
        <Border Name="hwndPlaceholder" />
    </Grid>
</Window>

```

The description of the Window.Loaded event here says

> Occurs when the element is laid out, rendered, and ready for
> interaction.

After setting it I get:

[![enter image description here](https://i.sstatic.net/49Ooj.png)](https://i.sstatic.net/49Ooj.png)


---

