Re: opengl win32 class member wndproc



michele wrote:

hi wolfgang, here's my code


void SetupRC2(HDC hDC)
{
glClearColor(0,0,0,1);
cout<<"color cleared"<<endl;

}

No, the color doesn't get cleared. All you set is the color that
will be used for clearing if the GL_COLOR_BUFFER_BIT is set in
the parameter to glClear.



void SetDCPixelFormat2(HDC hDC)
{
int nPixelFormat;
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
32,
0,0,0,0,0,0,
0,0,
0,0,0,0,0,
32,
0,
0,
0,
0,
0,0,0
};
nPixelFormat = ChoosePixelFormat(hDC, &pfd);
SetPixelFormat(hDC, nPixelFormat, &pfd);
}

void ChangeSize(GLsizei w, GLsizei h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-.5,.5,-.5,.5,1,1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

The whole projection matrix setup should be placed in the drawing
code. In many tutorials you'll find, that the projection is
setup in the windows resizing handler, but this is a lame style.
In a real world application you'll change the projection and
viewport a couple of times during rendering.



//window representation
HWND oglw;
HDC hDC;
HGLRC hRC;
eventlist dlist; //draw list


LRESULT CALLBACK
OpenGLWindow2::MainProc2(HWND hwnd, UINT message, WPARAM
wParam, LPARAM lParam)

Is OpenGLWindow2::MainProc2 a static member function? Because if
it's not...

OpenGLWindow2::
OpenGLWindow2(HWND parent,int xx,int yy,int width, int
height)
:oglw(NULL)
{
hDC=NULL;
hRC=NULL;
if(1)//registra la classe
{
WNDCLASSEX w;

char* c;
c=new char[16];strcpy(c,"OPENGLCLASSNAME");

w.lpszClassName=c;
w.cbSize=sizeof(WNDCLASSEX);
w.style=CS_DBLCLKS;

w.lpfnWndProc=MainProc2;
^^^^^^^^^^^^^^^^^^^^^^^^
This won't work. You can't use a class member function for a
callback. The problem is, that calling a class member function
requires a class instance on to operate on.

w.cbClsExtra = 0;
w.cbWndExtra = 0;
w.hInstance = 0;
w.hIcon = LoadIcon(NULL,IDI_APPLICATION);
w.hCursor = LoadCursor(NULL,IDC_ARROW);
w.hbrBackground = 0;
w.lpszMenuName = 0;
w.hIconSm = 0;

if(!RegisterClassEx(&w))cout<<"classe già
registrata"<<endl;
}

I don't get it: Why are you reinventing the wheel, and make it
square then? You're reinventing, because there are already
excellent C++ GUI class libraries for dealing with that kind of
stuff (Qt, GTK--, wxWidgets). And it's square because you're not
even scraping on the surface of OOP programming. What you try to
do looks like a poor man's attempt in reinventing the MFC.

Instead create some global hash map, putting the key in the
window attribute and the this pointer as the value. Add the
this pointer to the map in the constructor and remove it in
the destructor. Just derive all classes from a common root
class, and make the instances hash map a static member of that
root class.


can you explain me with some example?, cause you mention
entities that i don't know like hash map

A hash map is a map, that allows to access objects by a key
value. The problem by putting a pointer into GWL_USERDATA is,
that the length, or the arithmetic of the pointer may not match
with the Windows type LONG. So what we do, is creating a map,
that uniquely maps every object a numeric ID compatible with the
long type.

#include <map>

#include <windows.h>

class Object
{
LONG this_id;
static LONG object_id_serial;
typedef std::map<LONG, Object*> ObjectToLONGBimap;
static ObjectToLONGBimap objects;
Object() {
objects.insert(pair(this_id = ++object_id_serial, this));
}
virtual ~Object() {
object.erase(this_id);
}
}

LONG Object::object_id_serial=0;
Object::ObjectToLONGBimap Object::objects;

Now derive all objects from Object, and you can use the this_id
for GWL_USERDATA.

But normally you'd do it other way round: When creating the
window, you get a HWND handle. One can use that as a key for
accessing the object:

#include <map>

#include <windows.h>

class Window : Object
{
typedef std::map<HWND, Window*> HWNDToWindow;
static HWNDToWindow hwnd_to_window_map;
HWND hWnd;
void Create(...) {
//...
hWnd = CreateWindow(...);
//
hwnd_to_window_map.insert(pair(hWnd, this));
}

void OnDestroy() {
hwnd_to_window_map.erase(hWnd);
}
}

Window::HWNDToWindow Object::objects;

You can then use the hwnd_to_window_map to dispatch messages
based on their hWnd to the respective class instances.

after that i want to say you that above code works (relative
only to "windows" code);

You were lucky so far. From what I see here, this code is doomed
to fail miserably, some day.

Wolfgang

.



Relevant Pages

  • Re: How to detect printer is color printer
    ... void ErrorMsg(char * Message) ... void ListBasic(HDC hdc, HDC hdcInfo) ... BOOL APIENTRY PrinterProc(HWND hDlg, UINT msg, ...
    (microsoft.public.dotnet.languages.vb)
  • Re: Mouse Position
    ... VOID* pVertices; ... LONG WINAPI wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM ... HWND CrteWnd(const char *pszName, int x, int y, int w, int h) { ... // Create the application's window ...
    (microsoft.public.win32.programmer.directx.graphics)
  • Re: Why C?
    ... void RegisterAsciiEditor; ... HWND CreateAsciiEditor(HINSTANCE hInstance, int nCmdShow); ... LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); ... char *GetOpenFile; ...
    (comp.lang.c)
  • Re: DeviceIoControl returning ERROR_INVALID_PARAMETER
    ... void checkit; ... LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) ... DWORD WINAPI ThreadFunc ... unsigned int status = 0xfffffffe; ...
    (microsoft.public.development.device.drivers)
  • Re: Creating and adding controls
    ... As Check pointed out your CDialog class will have a hWnd after OnInitDialog. ... void CMyPropertySheet::DisplayWindow ... > does not support property sheet wizards. ...
    (microsoft.public.vc.mfc)