How to Create a CHILD OpenGL Window in a Dialog

Environment: VC6 Win 2000
For a while, I've been using glut (which is great) to create all of my OpenGL projects. This was fine for a while until I had to do some "crazy" things with subwindows. I figured if I just used MFC instead, all my problems would be solved. The only down side was trying to get a child opengl window in my dialog. I've seen a lot of examples using MDI and SDI, but I just would have felt cheated if I couldn't get it to work for a dialog. Through a little trial and error and a couple of passes through the MSDN, I offer you this quick and dirty example of how to do it.
The first thing you do is create a dialog based application. Next you can use the Class Wizard (by right clicking on the dialog form you see in your resource tab) to create a new class derived from a generic CWnd (I named mine COpenGL... quite original). After you've created your new class, use the class wizard to Set up the functions that handle the WM_CREATE and WM_PAINT messages. You can add other messages if you wish, but these are all we'll need for now.
Inside the generated dialog class header file (in my example it's called fastDlg.h), you'll want to add a pointer to your new class.
class CFastDlg : public CDialog
{
// Construction
public:
~CFastDlg(void);
CFastDlg(CWnd* pParent = NULL); // standard constructor
COpenGL *m_pDisplay; //<-- here he is!
.
.
.
Don't forget to add the header file at the top. You'll find the generated message handlers inside OpenGL.cpp. On creation of the window, I set its device context so it can handle opengl commands.
class CFastDlg : public CDialog
{
int COpenGL::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
MySetPixelFormat(::GetDC(m_hWnd));
return 0;
}
The code for MySetPixelFormat(...) was found in the MSDN. Inside OnPaint, I make the device context current, do my opengl commands, and make my dievice context non-current. I'm sure there are several different ways to do this, and you should do as much error checking as possible. But like I said before, this is a quick and dirty example ;)
void COpenGL::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
HDC hdc = ::GetDC(m_hWnd);
HGLRC hglrc;
// TODO: Add your message handler code here
glClearColor(0,0,0,0);
glColor3f(1, 1, 1);
if (hglrc = wglCreateContext(hdc))
{
// try to make it the thread's current rendering context
if(wglMakeCurrent(hdc, hglrc))
{
//render here
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glColor3f(1, 0, 0);
glVertex3f(.5, 0, 0);
glColor3f(0, 1, 0);
glVertex3f(0, .5, 0);
glColor3f(0, 0, 1);
glVertex3f(-.5, 0, 0);
glEnd();
SwapBuffers(hdc);
}
}
wglMakeCurrent(NULL, NULL) ;
::ReleaseDC (m_hWnd, hdc) ;
wglDeleteContext(hglrc);
// Do not call CWnd::OnPaint() for painting messages
}
The last important thing that you'll need to do is create the window in the OnInitDialog function.
BOOL CFastDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog.
// The framework does this automatically when
// the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
CRect rect(7, 7, 300, 300);
// TODO: Add extra initialization here
m_pDisplay->Create( NULL, //CWnd default
NULL, //has no name
WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_VISIBLE,
rect,
this, //this is the parent
0); //this should really be a different
// number... check resource.h
return TRUE; // return TRUE unless you set
// the focus to a control
}
I really hope this helps. I know I couldn't find a tutorial on creating a child window in a dialog, and I tried several other approaches before hitting this one. I'd also like to thank CodeGuru.com... there articles (and the people who submitted them) have helped out quite often.

Comments
thank you!
Posted by halciber on 04/28/2006 12:16pmThis was just thing I needed for work. You saved me a lot of trial and error. Like you, I've used GLUT windows; but I've never done OpenGL on MFC dialogs before. So seeing this has made my job easier. I really appreciate your help. Mike Goldweber
ReplyProblems to open new dialogs
Posted by Danseven on 03/22/2006 02:41pmI put a button to open a new dialog but the application crash after I click , this only because opengl, i cant open new dialogs becaus this, why?
Replypb with keydown events
Posted by gemyny on 07/28/2005 03:09amI got difficulties using OnKeydown events for the OpenGl window, do you have idea about the pb ? Thx a lot Regards GeMyNy
Replythanks
Posted by zygsq on 04/30/2005 11:46amit is great.i need such guiding too much.i met the similar problem in doing mu graduate thesis.thanks
ReplyAnd GDI ?
Posted by Legacy on 01/11/2004 12:00amOriginally posted by: sebseb
Hi, it's not really a comment, but more a question... how to do the same, but without MFC ? just as a normal win32 app with a WinMain and a WindowProc ?
Thank you in advance
ReplyQuestion - two GL windows in one Dlg - possible?
Posted by Legacy on 01/07/2004 12:00amOriginally posted by: Greg K
Is it possible to have two ( or more ) GL windows in one DLG? Like:
COpenGL* m_p_win1, m_p_win2;
BOOL CFastDlg::OnInitDialog()
{
CDialog::OnInitDialog();
m_p_win1->Create( NULL, //CWnd default
NULL, //has no name
WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_VISIBLE ,rect1,
this, //this is the parent 0); //this should really be a different number... check resource.h
// second gl window
m_p_win2->Create (
.
.
)
}
But they ( pointers ) refer to the same stucture, so the contents of both windows are equal, how can this be solved?
Adding new funtion to the structure? But this is not very good in case you have a lot of GL windows
Wanted to thank you - Cool! Fast and simple!
ReplyFull screen in opengl
Posted by Legacy on 12/26/2003 12:00amOriginally posted by: Luis Guerrero
I'm an ghj draw before the main window, an dialog?. Thanx.gg
ReplyVery nice, and thanks
Posted by Legacy on 08/13/2003 12:00amOriginally posted by: Amr Turk
I was working on a project that need an opengl window in a dialog box,and this would help. but mine is some how different.
I really would like to thank u very much for your effort.
Amr Turk
ReplyThanks!
Posted by Legacy on 07/15/2003 12:00amOriginally posted by: zhouys
Thanks!
ReplyThanks
Posted by Legacy on 06/05/2003 12:00amOriginally posted by: Manuel
After tests and tests i can load my openGl window in a mdi window. Thanks
ReplyLoading, Please Wait ...