From 87b501f0f76c77aa1a6b8836539d4b5eb7dd3fb2 Mon Sep 17 00:00:00 2001 From: Julian Smart Date: Thu, 28 Oct 1999 11:35:45 +0000 Subject: [PATCH] Added CS_OWNDC fix to wxGLCanvas and corrected sample makefiles git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4240 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/msw/cursor.cpp | 8 +- utils/glcanvas/samples/cube/makefile.vc | 7 +- utils/glcanvas/samples/isosurf/makefile.vc | 7 +- utils/glcanvas/samples/penguin/makefile.vc | 7 +- utils/glcanvas/win/glcanvas.cpp | 126 ++++++++++++++++++++- utils/glcanvas/win/glcanvas.h | 4 + utils/glcanvas/win/makefile.vc | 2 +- 7 files changed, 147 insertions(+), 14 deletions(-) diff --git a/src/msw/cursor.cpp b/src/msw/cursor.cpp index 56c4a8b9a3..b483ad0145 100644 --- a/src/msw/cursor.cpp +++ b/src/msw/cursor.cpp @@ -78,7 +78,7 @@ wxCursor::wxCursor(const wxString& cursor_file, long flags, int hotSpotX, int ho M_CURSORDATA->m_destroyCursor = FALSE; M_CURSORDATA->m_hCursor = 0; M_CURSORDATA->m_ok = FALSE; - if (flags & wxBITMAP_TYPE_CUR_RESOURCE) + if (flags == wxBITMAP_TYPE_CUR_RESOURCE) { #ifdef __WIN95__ M_CURSORDATA->m_hCursor = (WXHCURSOR) LoadImage(wxGetInstance(), cursor_file, IMAGE_CURSOR, 0, 0, 0); @@ -90,7 +90,7 @@ wxCursor::wxCursor(const wxString& cursor_file, long flags, int hotSpotX, int ho else M_CURSORDATA->m_ok = FALSE; } - else if (flags & wxBITMAP_TYPE_CUR) + else if (flags == wxBITMAP_TYPE_CUR) { #ifdef __WIN95__ M_CURSORDATA->m_hCursor = (WXHCURSOR) LoadImage(wxGetInstance(), cursor_file, IMAGE_CURSOR, 0, 0, LR_LOADFROMFILE); @@ -101,14 +101,14 @@ wxCursor::wxCursor(const wxString& cursor_file, long flags, int hotSpotX, int ho #endif #endif } - else if (flags & wxBITMAP_TYPE_ICO) + else if (flags == wxBITMAP_TYPE_ICO) { #if wxUSE_RESOURCE_LOADING_IN_MSW M_CURSORDATA->m_hCursor = (WXHCURSOR) IconToCursor(WXSTRINGCAST cursor_file, wxGetInstance(), hotSpotX, hotSpotY, &M_CURSORDATA->m_width, &M_CURSORDATA->m_height); M_CURSORDATA->m_destroyCursor = TRUE; #endif } - else if (flags & wxBITMAP_TYPE_BMP) + else if (flags == wxBITMAP_TYPE_BMP) { #if wxUSE_RESOURCE_LOADING_IN_MSW HBITMAP hBitmap = 0; diff --git a/utils/glcanvas/samples/cube/makefile.vc b/utils/glcanvas/samples/cube/makefile.vc index 997616ea30..f944029f9e 100644 --- a/utils/glcanvas/samples/cube/makefile.vc +++ b/utils/glcanvas/samples/cube/makefile.vc @@ -11,10 +11,15 @@ # Set WXDIR for your system WXDIR = $(WXWIN) +!if "$(FINAL)" == "1" +!else +LIBEXT=_d +!endif + PROGRAM=cube OBJECTS = $(PROGRAM).obj EXTRAINC=-I..\..\win -EXTRALIBS=$(WXDIR)\lib\glcanvas.lib glu32.lib opengl32.lib +EXTRALIBS=$(WXDIR)\lib\glcanvas$(LIBEXT).lib glu32.lib opengl32.lib !include $(WXDIR)\src\makeprog.vc diff --git a/utils/glcanvas/samples/isosurf/makefile.vc b/utils/glcanvas/samples/isosurf/makefile.vc index be397eddd6..7da10310ff 100644 --- a/utils/glcanvas/samples/isosurf/makefile.vc +++ b/utils/glcanvas/samples/isosurf/makefile.vc @@ -11,10 +11,15 @@ # Set WXDIR for your system WXDIR = $(WXWIN) +!if "$(FINAL)" == "1" +!else +LIBEXT=_d +!endif + PROGRAM=isosurf OBJECTS = $(PROGRAM).obj EXTRAINC=-I..\..\win -EXTRALIBS=$(WXDIR)\lib\glcanvas.lib glu32.lib opengl32.lib +EXTRALIBS=$(WXDIR)\lib\glcanvas$(LIBEXT).lib glu32.lib opengl32.lib EXTRATARGETS=isosurf.dat !include $(WXDIR)\src\makeprog.vc diff --git a/utils/glcanvas/samples/penguin/makefile.vc b/utils/glcanvas/samples/penguin/makefile.vc index 27e4721eaa..32e14d829c 100644 --- a/utils/glcanvas/samples/penguin/makefile.vc +++ b/utils/glcanvas/samples/penguin/makefile.vc @@ -11,10 +11,15 @@ # Set WXDIR for your system WXDIR = $(WXWIN) +!if "$(FINAL)" == "1" +!else +LIBEXT=_d +!endif + PROGRAM=penguin OBJECTS = $(PROGRAM).obj trackball.obj lw.obj EXTRAINC=-I..\..\win -EXTRALIBS=$(WXDIR)\lib\glcanvas.lib glu32.lib opengl32.lib +EXTRALIBS=$(WXDIR)\lib\glcanvas$(LIBEXT).lib glu32.lib opengl32.lib !include $(WXDIR)\src\makeprog.vc diff --git a/utils/glcanvas/win/glcanvas.cpp b/utils/glcanvas/win/glcanvas.cpp index e90b555a01..fd1e1ef44b 100644 --- a/utils/glcanvas/win/glcanvas.cpp +++ b/utils/glcanvas/win/glcanvas.cpp @@ -23,8 +23,15 @@ #include #endif +#include + #include "glcanvas.h" +wxChar wxGLCanvasClassName[] = wxT("wxGLCanvasClass"); + +LRESULT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, + WPARAM wParam, LPARAM lParam); + /* * GLContext implementation */ @@ -131,18 +138,28 @@ wxGLCanvas::wxGLCanvas(wxWindow *parent, wxWindowID id, m_glContext = new wxGLContext(TRUE, this, palette); } + wxGLCanvas::wxGLCanvas( wxWindow *parent, const wxGLContext *shared, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name, - int *attribList, const wxPalette& palette ) : - wxScrolledWindow(parent, id, pos, size, style, name) + int *attribList, const wxPalette& palette ) + : wxScrolledWindow() +// : wxScrolledWindow(parent, id, pos, size, style, name) { - m_hDC = (WXHDC) ::GetDC((HWND) GetHWND()); + bool ret = Create(parent, id, pos, size, style, name); - SetupPixelFormat(); - SetupPalette(palette); + if ( ret ) + { + SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE)); + SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT)); + } - m_glContext = new wxGLContext(TRUE, this, palette, shared ); + m_hDC = (WXHDC) ::GetDC((HWND) GetHWND()); + + SetupPixelFormat(); + SetupPalette(palette); + + m_glContext = new wxGLContext(TRUE, this, palette, shared ); } wxGLCanvas::~wxGLCanvas() @@ -153,6 +170,103 @@ wxGLCanvas::~wxGLCanvas() ::ReleaseDC((HWND) GetHWND(), (HDC) m_hDC); } +// Replaces wxWindow::Create functionality, since we need to use a different window class +bool wxGLCanvas::Create(wxWindow *parent, wxWindowID id, + const wxPoint& pos, const wxSize& size, long style, const wxString& name) +{ + static bool registeredGLCanvasClass = FALSE; + + // We have to register a special window class because we need + // the CS_OWNDC style for GLCanvas. + +/* + Here are two snips from a dicussion in the OpenGL Gamedev list that explains + how this problem can be fixed: + + "There are 5 common DCs available in Win95. These are aquired when you call + GetDC or GetDCEx from a window that does _not_ have the OWNDC flag. + OWNDC flagged windows do not get their DC from the common DC pool, the issue + is they require 800 bytes each from the limited 64Kb local heap for GDI." + + "The deal is, if you hold onto one of the 5 shared DC's too long (as GL apps + do), Win95 will actually "steal" it from you. MakeCurrent fails, + apparently, because Windows re-assigns the HDC to a different window. The + only way to prevent this, the only reliable means, is to set CS_OWNDC." +*/ + + if (!registeredGLCanvasClass) + { + WNDCLASS wndclass; + + static const long styleNormal = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC; + + // the fields which are common to all classes + wndclass.lpfnWndProc = (WNDPROC)wxWndProc; + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = sizeof( DWORD ); // VZ: what is this DWORD used for? + wndclass.hInstance = wxhInstance; + wndclass.hIcon = (HICON) NULL; + wndclass.hCursor = ::LoadCursor((HINSTANCE)NULL, IDC_ARROW); + wndclass.lpszMenuName = NULL; + + // Register the GLCanvas class name + wndclass.hbrBackground = (HBRUSH)NULL; + wndclass.lpszClassName = wxGLCanvasClassName; + wndclass.style = styleNormal; + + if ( !RegisterClass(&wndclass) ) + { + wxLogLastError("RegisterClass(wxGLCanvasClass)"); + + return FALSE; + } + } + + wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindow without parent") ); + + if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) ) + return FALSE; + + parent->AddChild(this); + + DWORD msflags = 0; + if ( style & wxBORDER ) + msflags |= WS_BORDER; + if ( style & wxTHICK_FRAME ) + msflags |= WS_THICKFRAME; + + msflags |= WS_CHILD | WS_VISIBLE; + if ( style & wxCLIP_CHILDREN ) + msflags |= WS_CLIPCHILDREN; + + bool want3D; + WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D); + + // Even with extended styles, need to combine with WS_BORDER + // for them to look right. + if ( want3D || (m_windowStyle & wxSIMPLE_BORDER) || (m_windowStyle & wxRAISED_BORDER ) || + (m_windowStyle & wxSUNKEN_BORDER) || (m_windowStyle & wxDOUBLE_BORDER)) + { + msflags |= WS_BORDER; + } + + // calculate the value to return from WM_GETDLGCODE handler + if ( GetWindowStyleFlag() & wxWANTS_CHARS ) + { + // want everything: i.e. all keys and WM_CHAR message + m_lDlgCode = DLGC_WANTARROWS | DLGC_WANTCHARS | + DLGC_WANTTAB | DLGC_WANTMESSAGE; + } + + MSWCreate(m_windowId, parent, wxGLCanvasClassName, this, NULL, + pos.x, pos.y, + WidthDefault(size.x), HeightDefault(size.y), + msflags, NULL, exStyle); + + return TRUE; + +} + void wxGLCanvas::SetupPixelFormat() // (HDC hDC) { PIXELFORMATDESCRIPTOR pfd = { diff --git a/utils/glcanvas/win/glcanvas.h b/utils/glcanvas/win/glcanvas.h index 186df14faf..6dd7e60c6c 100644 --- a/utils/glcanvas/win/glcanvas.h +++ b/utils/glcanvas/win/glcanvas.h @@ -79,6 +79,10 @@ class wxGLCanvas: public wxScrolledWindow ~wxGLCanvas(); + // Replaces wxWindow::Create functionality, since we need to use a different window class + bool Create(wxWindow *parent, wxWindowID id, + const wxPoint& pos, const wxSize& size, long style, const wxString& name); + void SetCurrent(); void SetColour(const char *colour); void SwapBuffers(); diff --git a/utils/glcanvas/win/makefile.vc b/utils/glcanvas/win/makefile.vc index 077cb40324..ebe99e4e97 100644 --- a/utils/glcanvas/win/makefile.vc +++ b/utils/glcanvas/win/makefile.vc @@ -15,7 +15,7 @@ WXDIR = $(WXWIN) GLDIR = $(WXDIR)\utils\glcanvas THISDIR = $(GLDIR)\win -EXTRALIBS=$(WXDIR)\lib\glcanvas.lib +EXTRALIBS=$(WXDIR)\lib\glcanvas$(LIBEXT).lib DOCDIR=$(WXDIR)\docs LOCALDOCDIR=$(WXDIR)\utils\glcanvas\docs -- 2.47.2