invalid use of member ' ' in static member function

Iniciado por CBFD, 9 Junio 2016, 10:56 AM

0 Miembros y 1 Visitante están viendo este tema.

CBFD

Hola a todos:

En primer lugar soy muy novato con C++ y estoy haciendo una clase para crear ventanas hijas y en ellas escribir textos, la clase es la siguiente:

Código ( c) [Seleccionar]

#include <windows.h>
#include <string>

using namespace std;

#if !defined(ClaseTSay)
#define ClaseTSay

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class TSay
{
private:
static LRESULT CALLBACK  WinProc(HWND vHij, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_PAINT :
{
HDC dc  = GetDC(vHij);
PAINTSTRUCT ps;
RECT rc;
HRGN bgRgn;
HBRUSH hBrush;
HGDIOBJ old;

  int x_posX = (int)posX;
int x_posY = (int)posY;
int x_tamX = (int)tamX;
int x_tamY = (int)tamY;

dc = BeginPaint (vHij, &ps);
SetRect (&rc, 0, 0, x_tamX, x_tamY);
bgRgn = CreateRectRgnIndirect(&rc);
hBrush = CreateSolidBrush(fond);
FrameRgn(dc, bgRgn, hBrush,2,2);
SetBkMode    (dc, fond);
SetTextColor (dc, escr);
old = SelectObject(dc, letr);

switch (m_alin)
{
case 0:
DrawText(dc, pint, lstrlen(pint), &rc, DT_LEFT | DT_VCENTER );
break;
case 1:
DrawText(dc, pint, lstrlen(pint), &rc, DT_CENTER | DT_VCENTER );
break;
case 2:
DrawText(dc, pint, lstrlen(pint), &rc, DT_RIGHT | DT_VCENTER );
break;
}


SelectObject(dc, old);
ReleaseDC(vHij, dc);
DeleteObject(old);
DeleteObject(bgRgn);
DeleteObject(hBrush);
    EndPaint (vHij, &ps);
    break;
}
default :
return DefWindowProc(vHij, uMsg, wParam, lParam);
}
return 0;
}
protected:
HWND      vHij;
WNDPROC  oldW;
double      posX;
double      posY;
const char* pint;
HWND        vent;
HFONT       letr;
COLORREF    escr;
COLORREF    fond;
double      tamX;
double      tamY;
int         bord;
int         alin;
const TCHAR *cVen;
public:
TSay()
{
vHij = NULL;
oldW = NULL;
posX = 0;
posY = 0;
pint = NULL;
vent = NULL;
letr = NULL;
escr = 00;
fond = 0;
tamX = 0;
tamY = 0;
bord = 0;
alin = 0;
cVen = NULL;
}

~TSay()
{
}

HWND Crear( double posX, double posY, const char* pint, HWND vent, HFONT letr, COLORREF escr, COLORREF fond, double tamX, double tamY, int bord, int alin, const TCHAR *cVen)
{
DWORD hPen;
if (bord == 1)
{
hPen = WS_BORDER | WS_CHILD| WS_VISIBLE;
}
else
{
hPen = WS_CHILD| WS_VISIBLE;
}

WNDCLASSEX WndClass;

WndClass.cbSize = sizeof(WNDCLASSEX);
WndClass.style = 0;
WndClass.lpfnWndProc = WinProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = GetModuleHandle(NULL);
WndClass.hIcon = NULL;
WndClass.hIconSm = NULL;
WndClass.hCursor = LoadCursor(0, IDC_ARROW);
WndClass.hbrBackground = (HBRUSH)CreateSolidBrush(fond);
WndClass.lpszMenuName = 0;
WndClass.lpszClassName = cVen;

RegisterClassEx(&WndClass);

  int x_posX = (int)posX;
int x_posY = (int)posY;
int x_tamX = (int)tamX;
int x_tamY = (int)tamY;

vHij = CreateWindowEx(
0,
cVen,
"TSay",
hPen,
    x_posY,
    x_posX,
    x_tamX,
    x_tamY,
vent,
    NULL,
GetModuleHandle(NULL),
    NULL);

if(vHij)
{
ShowWindow(vHij, 5);
    UpdateWindow(vHij);
}
return vHij;
}
};
#endif // !defined(ClaseTSay)
:

Mi problema es que en las líneas 73, 74, 75, 77, 78, 79, 80 y 81 me da el error de "invalid use of member ' ' in static member function" y en las líneas entre la 29 y la 52 que las usan en WM_PAINT me pone "from this location".

Me podéis orientar para poder solucionar este problema.

Un saludo y gracias.

Carlos


ivancea96

Veamos. En un static, no estás trabajando con ningún objeto, por tanto, no hay miembros con los que trabajar (salvo otros miembros static.

Para acceder a los miembros de ese objeto TSay, tendrás primero que obtener ese objeto. CreateWindowEx tiene un parámetro, el último, que es el LPARAM que recibirá la función en el mensaje WM_CREATE. Puedes pasarle por ahí un puntero al objeto, por ejemplo.

Aunque claro, así solo sabrás ese dato la primera vez. Para conocer el objeto de TSay en cada llamada, algo que puedes hacer es almacenarlo en otro miembro static, y utilizar ese miembro las próximas llamadas al callback.

Por ejemplo, yo haría un map<LONG, TSay*>, donde el LONG sería el identificador de la ventana, que obtienes con la función GetWindowLong.

Ciertamente esta parte tiene algo más de enjundia, pero bueno. Una vez hecho, hecho queda xD

CBFD

Hola de nuevo:

Ya he conseguido mucho y casi tengo todo hecho pero me falta todavía una cosa que no se porque pasa.

El código es ahora así:


#if !defined(TSAY)
    #define TSAY

   #include <windows.h>

    WNDCLASS   wc;
    HWND       vHij;

const char* pint;
HFONT       letr;
    COLORREF    escr;
    double      tamX;
double      tamY;
int         alin;

    class TSay
    {
    protected:
        static LRESULT CALLBACK WinProc(HWND vHij, UINT msg, WPARAM wParam, LPARAM lParam)
        {
            switch(msg)
            {
                case WM_DESTROY:
                    PostQuitMessage(0);
                    break;
                default:
                    return DefWindowProc(vHij, msg, wParam, lParam);
            }
            return 0;
        }
    public:
        TSay()
        {
        }
        ~TSay()
        {
        }
        HWND Crear(HINSTANCE hIns,double posX, double posY, const char* pint, HWND vent, HFONT letr, COLORREF escr, COLORREF fond, double tamX, double tamY, int bord, int alin, const char *cVen)
        {
WNDCLASSEX WndClass;

WndClass.cbSize = sizeof(WNDCLASSEX);
WndClass.style = 0;
WndClass.lpfnWndProc = WinProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = hIns;
WndClass.hIcon = NULL;
WndClass.hIconSm = NULL;
WndClass.hCursor = LoadCursor(0, IDC_ARROW);
WndClass.hbrBackground = (HBRUSH)CreateSolidBrush(fond);
WndClass.lpszMenuName = 0;
WndClass.lpszClassName = cVen;

RegisterClassEx(&WndClass);

DWORD hPen;
if (bord == 1)
{
hPen = WS_BORDER | WS_CHILD| WS_VISIBLE;
}
else
{
hPen = WS_CHILD| WS_VISIBLE;
}

  int x_posX = (int)posX;
int x_posY = (int)posY;
int x_tamX = (int)tamX;
int x_tamY = (int)tamY;

vHij = CreateWindow(
cVen,
"TSay",
hPen,
    x_posY,
    x_posX,
    x_tamX,
    x_tamY,
vent,
    NULL,
    hIns,
    NULL);

ShowWindow(vHij, 5);
RedrawWindow(vHij,NULL,NULL,RDW_INVALIDATE | RDW_INTERNALPAINT);

HDC dc  = GetDC(vHij);
PAINTSTRUCT ps;
RECT rc;
HRGN bgRgn;
HBRUSH hBrush;
HGDIOBJ old;

dc = BeginPaint (vHij, &ps);
SetRect (&rc, 0, 0, x_tamX, x_tamY);
bgRgn = CreateRectRgnIndirect(&rc);
hBrush = CreateSolidBrush(fond);
FrameRgn(dc, bgRgn, hBrush,2,2);
SetBkMode    (dc, TRANSPARENT);
SetTextColor (dc, escr);
old = SelectObject(dc, letr);

switch (alin)
{
case 0:
DrawText(dc, pint, lstrlen(pint), &rc, DT_LEFT | DT_VCENTER );
break;
case 1:
DrawText(dc, pint, lstrlen(pint), &rc, DT_CENTER | DT_VCENTER );
break;
case 2:
DrawText(dc, pint, lstrlen(pint), &rc, DT_RIGHT | DT_VCENTER );
break;
}


SelectObject(dc, old);
ReleaseDC(vHij, dc);
DeleteObject(old);
DeleteObject(bgRgn);
DeleteObject(hBrush);
    EndPaint (vHij, &ps);

RedrawWindow(vHij,NULL,NULL,RDW_INVALIDATE | RDW_INTERNALPAINT);

return vHij;
}
};
#endif // TSAY


Y crea las ventanas corectamente pero no me incorpora los textos que quiero esto lo debería hacer con las líneas de la 88 a 123. pero no lo pone. Estoy haciendo todo tipo de pruebas con eclipse y haciendo el debug cuando paro entre impresiones si me las pone pero luego cuando finaliza la función y refresca la ventana donde van desaparecen y quedan las ventanas sin textos.

la función que llama a esta clase es :


void Pantalla()
{
  TSay   oSay  = TSay  ();
  oPan4     = oSay.Crear(hInstance,  10*TamPan, 30*TamPan, wtex000, oDlgwVen, oFont, escri1, fondo2,1020*TamPan, 77*TamPan, 0, 0, "oPan4");
  oPan401   = oSay.Crear(hInstance,  25*TamPan,340*TamPan, wtex001, oPan4   , oFon3, escri3, fondo1, 630*TamPan, 30*TamPan, 1, 1, "oPan401");
  oMenPan   = oSay.Crear(hInstance,  95*TamPan, 30*TamPan, wtex000, oDlgwVen, oFont, escri3, fondo1, 245*TamPan,555*TamPan, 0, 0, "oMenPan");
  oMenPan01 = oSay.Crear(hInstance,  22*TamPan, 30*TamPan, wtex002, oMenPan , oFont, escri1, fondo1, 200*TamPan, 28*TamPan, 0, 0, "oMenPan01");
  oMenPan02 = oSay.Crear(hInstance,  52*TamPan, 30*TamPan, wtex003, oMenPan , oFont, escri1, fondo1, 200*TamPan, 28*TamPan, 0, 0, "oMenPan02");
  oMenPan03 = oSay.Crear(hInstance,  82*TamPan, 30*TamPan, wtex004, oMenPan , oFont, escri1, fondo1, 200*TamPan, 28*TamPan, 0, 0, "oMenPan03");
  oMenPan04 = oSay.Crear(hInstance, 112*TamPan, 30*TamPan, wtex008, oMenPan , oFont, escri1, fondo1, 200*TamPan, 28*TamPan, 0, 0, "oMenPan04");
  oMenPan05 = oSay.Crear(hInstance, 142*TamPan, 30*TamPan, wtex009, oMenPan , oFont, escri1, fondo1, 200*TamPan, 28*TamPan, 0, 0, "oMenPan05");
  oMenPan06 = oSay.Crear(hInstance, 172*TamPan, 30*TamPan, wtex010, oMenPan , oFont, escri1, fondo1, 200*TamPan, 28*TamPan, 0, 0, "oMenPan06");
  oMenPan07 = oSay.Crear(hInstance, 202*TamPan, 30*TamPan, wtex011, oMenPan , oFont, escri1, fondo1, 200*TamPan, 28*TamPan, 0, 0, "oMenPan07");
  oMenPan08 = oSay.Crear(hInstance, 232*TamPan, 30*TamPan, wtex012, oMenPan , oFont, escri1, fondo1, 200*TamPan, 28*TamPan, 0, 0, "oMenPan08");
  oMenPan09 = oSay.Crear(hInstance, 262*TamPan, 30*TamPan, wtex013, oMenPan , oFont, escri1, fondo1, 200*TamPan, 28*TamPan, 0, 0, "oMenPan09");
  oPant     = oSay.Crear(hInstance,  95*TamPan,300*TamPan, wtex001, oDlgwVen, oFont, escri1, fondo2, 750*TamPan,555*TamPan, 1, 0, "oPant");
  oPan2     = oSay.Crear(hInstance, 117*TamPan, 30*TamPan, wtex001, oDlgwVen, oFont, escri1, fondo2, 280*TamPan, 25*TamPan, 0, 0, "oPan2");

    RedrawWindow(oDlgwVen,NULL,NULL,RDW_INVALIDATE | RDW_INTERNALPAINT);
}


Alguna ayuda por favor.

Un saludo, gracias.

Carlos

CBFD

Os dejo las imágenes de cuando estoy haceindo el debug :



y cuando termina la función y refresca la pantalla:



Un saludo.

Carlos.