Jump to content

CreateWindow problema com o CPU


pikax
 Share

Recommended Posts

Boas

Estou a criar uma class que me fac,a crie uma janela, so que estava-me a dar um erro, que com um pouco de pesquisa consegui resolver, so que agora, o CPU esta atingir +30% na aplicacao, que eu acho ridiculo, sei que e' por causa de uma funcao estatica que tenho, mas nao sei o que fazer para melhora.la.

Estre codigo e' o codigo que foi dado na resposta neste topico

//
// Header
//
class Window
{
public:
   //...

protected:
   static LRESULT CALLBACK StaticWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
   LRESULT WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam);

protected:
   HWND   m_hWnd;
};

//
// Source
//
// When you register the window class, pass CWindow::StaticWndProc as the window message procedure pointer

// When you create the window, pass "this" as the extra parameter
m_hWnd = CreateWindowEx(0,"Classname","Title",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,320,200,NULL,NULL,hInstance,this);

// Now for the real code:
LRESULT CALLBACK CWindow::StaticWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
CWindow* pParent;

   // Get pointer to window
   if(uMsg == WM_CREATE)
   {
      pParent = (CWindow*)((LPCREATESTRUCT)lParam)->lpCreateParams;
      SetWindowLongPtr(hWnd,GWL_USERDATA,(LONG_PTR)pParent);
   }
   else
   {
      pParent = (CWindow*)GetWindowLongPtr(hWnd,GWL_USERDATA);
      if(!pParent) return DefWindowProc(hWnd,uMsg,wParam,lParam);
   }

   pParent->m_hWnd = hWnd;
   return pParent->WndProc(uMsg,wParam,lParam);
}

LRESULT CWindow::WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
   switch(uMsg)
   {
      // Normal code here
   }

   // Call default window proc if we haven't handled the message
   return DefWindowProc(m_hWnd,uMsg,wParam,lParam);
}

 

O problema que eu tinha, era igual ao da pessoa que criou o topico, mas agr com a resposta que deram(o codigo em cima), o problema ficou resolvido, so' que esta a consumir um CPU ridiculo.

Sei que podia usar o GTK, etc... mas quero fazer manualmente(gosto de trabalhar 😛 )

Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender.

A beleza de um código está em decompor problemas complexos em pequenos blocos simples.

"learn how to do it manually first, then use the wizzy tool to save time."

"Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast."

Link to comment
Share on other sites

estas a usar mais do que uma janela ???

ideia de solução :

porque não usas uma factory de janelas ... assim podias mandar o wndproc para uma função estática sem problemas através do ponteiro hWnd

exemplo:

class WindowFactory {
  protected:
    map<HWND, Window *> windows;

    WindowFactory() {};

  public:
    static Window * window(...); // criar janela ... adiciona os parametros
    static Window * window(HWND hwnd); // get da janela
}

static function WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
  return WindowFactory::window(hwnd)->WndProc(hwnd, msg, wParam, lParam);
}
IRC : sim, é algo que ainda existe >> #p@p
Link to comment
Share on other sites

Estou a pensar em poder criar mais que uma janela.

O codigo que pos em cima funciona, so que penso que a funcao "StaticWndProc" esteja a consumir muito, porque fiz uns break-points e passava sempre por essa funcao...

usando o que tu meteste aqui, recomecei todo de novo, mesmo assim, estas funções estáticas já dão nervos 😛

header

#ifndef cWindow_h__
#define cWindow_h__
#include <windows.h>
#include "../defines.h"
#include <map>

class cWindow
{
public:
cWindow();
~cWindow();

bool		InitNewWindow();
HWND		*GetWndHandler(){return &m_WindowsHandler;}

LRESULT CALLBACK WndProc(HWND hwnd,U32 uMsg, WPARAM  wParam,LPARAM  lParam);
protected:
HWND		m_WindowsHandler;
};


class cWindowFactory
{
public:
cWindowFactory();
bool AddNewWindow();

static cWindow * Window();			// criar janela ... adiciona os parametros
static cWindow * Window(HWND hwnd)	// get da janela
{
	return ;
}

protected:
std::map<HWND,cWindow*>	m_windows;
};



#endif // cWindow_h__

cpp

#include "cWindow.h"
#include "../defines.h"

static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 
{
return cWindowFactory::Window(hwnd)->WndProc(hwnd, msg, wParam, lParam);
}


cWindow *cWindowFactory::Window()
{
WNDCLASSEX wcex;
cWindow *window=new cWindow;
HINSTANCE hInstance;
HWND	*tempHWND=window->GetWndHandler();


if(window==NULL)
	return false;

/* register window class */
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_OWNDC;
wcex.lpfnWndProc = (WNDPROC) ::WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = L"GLSample";
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);;


if (!RegisterClassEx(&wcex))
	return 0;

*tempHWND=CreateWindowEx(0,
										L"GLSample",
										L"OpenGL Sample",
										WS_OVERLAPPEDWINDOW,
										CW_USEDEFAULT,
										CW_USEDEFAULT,
										256,
										256,
										NULL,
										NULL,
										hInstance,
										NULL);
if(!(*tempHWND))
{
	return 0;
}

ShowWindow(*tempHWND,SW_SHOWNORMAL);

m_windows.insert(pair<tempHWND,window); // nao consigo aceder
return window;
}



LRESULT CALLBACK cWindow::WndProc(HWND hwnd,U32 uMsg, WPARAM  wParam,LPARAM  lParam);
{
switch (uMsg)
{
case WM_CLOSE:
	PostQuitMessage(0);
	break;

case WM_DESTROY:
	return 0;

case WM_KEYDOWN:
	{
		switch (wParam)
		{
		case VK_ESCAPE:
			PostQuitMessage(0);
			break;
		}
		printf("just went down!\n");
	}
	break;

default:
	return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

return 0;
}

Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender.

A beleza de um código está em decompor problemas complexos em pequenos blocos simples.

"learn how to do it manually first, then use the wizzy tool to save time."

"Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast."

Link to comment
Share on other sites

não estás a implementar a factory como deve ser

class cWindowFactory
{
public:
        static cWindow * Window(); {
                cWindow * created = NULL;

                if (cWindowFactory::factory == NULL)
                    cWindowFactory::factory = new cWindowFactory();

               // criar janela
               ...

               // guardar janela no map
               cWindowFactory::factory->windows[created->GetWndHandler()] = created;

                return created;
        }
        static cWindow * Window(HWND hwnd) {
                if (cWindowFactory::factory == NULL)
                    cWindowFactory::factory = new cWindowFactory();

                return cWindowFactory::factory->windows[hwnd];
        }

protected:
       cWindowFactory() {
       }

        std::map<HWND,cWindow*> m_windows;
        static cWindowFactory * factory = NULL; 
};

desta maneira podes sempre obter o ponteiro da classe cWindow através do HWND com este código:

cWindow * window = cWindowFactory::window(hwnd);

assim podes incrementar a factory para passar o WndProc para a janela pretendida :

class cWindowFactory
{
public:
...
    static function LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
      return this->window(hwnd)->WndProc(hwnd, msg, wParam, lParam);
    }
...
}
IRC : sim, é algo que ainda existe >> #p@p
Link to comment
Share on other sites

Era mesmo isso... isto de variáveis/funções estáticas tem uns belos truques 😛

Essa forma fica mais fácil de criar windows novas, e a funcao fica muito mais limpa, do que a outra que eu postei no inicio.

Agora tenho que tratar dos "memory leaks" que estou a ter.

EDIT:

Estive a ver no Debugger e esta sempre a dar-me o "Erro CXX0030 - Expression cannot be evaluated"

461505_348749538504795_100001092540882_918537_724261451_o.jpg

header

#ifndef cWindow_h__
#define cWindow_h__
#include <windows.h>
#include "../defines.h"
#include <map>
#include <iostream>

class cWindow
{
public:
cWindow(){}
~cWindow(){}

bool	InitNewWindow();

void	SetHandler(HWND hwnd)
{
	m_WindowsHandler=hwnd;
}

HWND		*GetWndHandler(){return &m_WindowsHandler;}
HDC			GetHandlerDeviceContext(){return m_HandlerDeviceContext;}
void		MessageProc();

LRESULT CALLBACK WndProc(HWND hwnd,U32 uMsg, WPARAM  wParam,LPARAM  lParam);
private:
HWND		m_WindowsHandler;
HDC			m_HandlerDeviceContext;
};


class cWindowFactory
{
public:
cWindowFactory(){}

static cWindow * Window();			// criar janela ... adiciona os parametros
static cWindow * Window(HWND hwnd)	// get da janela
{
	if (cWindowFactory::factory == NULL)
	{
		std::cout<<"factoru nao inicializada\n";
		cWindowFactory::factory = new cWindowFactory();
	}

	return cWindowFactory::factory->m_windows[hwnd];
}

bool InitWindow();

void ProcessWindowMessage();
protected:

std::map<HWND,cWindow*>	m_windows;

static cWindowFactory *factory;

static HINSTANCE	m_hInstance;
};



#endif // cWindow_h__

cpp

#include "cWindow.h"
#include "../defines.h"
#include <cstdio>
#include <iostream>

cWindowFactory* cWindowFactory::factory=NULL;
HINSTANCE cWindowFactory::m_hInstance;

static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 
{
return cWindowFactory::Window(hwnd)->WndProc(hwnd, msg, wParam, lParam);
}

void cWindow::MessageProc()
{
MSG msg;

if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
{ 
	if (GetMessage(&msg, NULL, 0, 0) ) 
	{ 
		TranslateMessage(&msg); 
		DispatchMessage(&msg); 

	}
} 

return;
}

bool cWindowFactory::InitWindow()
{
if (cWindowFactory::factory == NULL)
	cWindowFactory::factory = new cWindowFactory();

WNDCLASS wc;

wc.style         = CS_HREDRAW | CS_VREDRAW; 
wc.lpfnWndProc   = ::WndProc; 
wc.cbClsExtra    = 0; 
wc.cbWndExtra    = 0; 
wc.hInstance     = m_hInstance; 
wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION); 
wc.hCursor       = LoadCursor (NULL,IDC_ARROW); 
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); 
wc.lpszMenuName  = L"GLSample";
wc.lpszClassName = L"GLSample"; 

if(!RegisterClass(&wc))
{
	OUTPUTDEBUGTEXT("Error RegisterClass\n");
	return 0;
}
return true;
}

cWindow *cWindowFactory::Window()
{
static cWindowFactory * factory = NULL;

cWindow *window=new cWindow;
HWND	tempHWND;
if(window==NULL)
{
	OUTPUTDEBUGTEXT("Error a new Window, out of memory???\n");
	return 0;
}

tempHWND=CreateWindow(	L"GLSample",
						L"Generic OpenGL Sample", 
						WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 
						CW_USEDEFAULT, 
						CW_USEDEFAULT, 
						300, 
						300, 
						NULL, 
						NULL, 
						m_hInstance,
						NULL); 
if(!tempHWND)
{
	OUTPUTDEBUGTEXT("error on tempHWND!\n");	
	return 0;
}

window->SetHandler(tempHWND);
// save window on map
cWindowFactory::factory->m_windows.insert(std::pair<HWND,cWindow*>(tempHWND,window));


ShowWindow(tempHWND,SW_SHOWNORMAL);	

return window;
}



LRESULT CALLBACK cWindow::WndProc(HWND hwnd,U32 uMsg, WPARAM  wParam,LPARAM  lParam)
{
LONG    lRet = 1; 
//HDC	hDC =  pThis->GetHandlerDeviceContext();
HDC		hDC=m_HandlerDeviceContext;

switch (uMsg) { 

case WM_CREATE: 
	hDC = GetDC(hwnd); 

	break;

case WM_PAINT: 
	break; 

case WM_SIZE: 

	break; 

case WM_CLOSE: 
	//if (ghRC) 
		//wglDeleteContext(ghRC); 
	if (hDC) 
	{
		ReleaseDC(hwnd, hDC); 
		hDC = 0; 
	}
	//ghRC = 0; 
	DestroyWindow (hwnd); 
	PostQuitMessage(0);
	break; 

case WM_DESTROY: 
	//if (ghRC) 
	//wglDeleteContext(ghRC); 
	if (hDC) 
		ReleaseDC(hwnd, hDC);  

	PostQuitMessage (0); 
	break; 

case WM_KEYDOWN: 
	switch (wParam) 
	{ 
	case VK_LEFT: 

		break; 
	case VK_RIGHT: 

		break; 
	case VK_UP: 

		break; 
	case VK_DOWN: 

		break; 
	} 

default: 
	lRet=DefWindowProc (hwnd, uMsg, wParam, lParam); 
	break; 
} 

return lRet; 
}

void cWindowFactory::ProcessWindowMessage()
{
std::map<HWND,cWindow*>::const_iterator it;

for(it=cWindowFactory::factory->m_windows.begin();it!=cWindowFactory::factory->m_windows.end();++it)
{
	(*it).second->MessageProc();
}
}

Estou a conseguir criar as janelas, mas nao estou a conseguir aceder aos membros do apontador...

Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender.

A beleza de um código está em decompor problemas complexos em pequenos blocos simples.

"learn how to do it manually first, then use the wizzy tool to save time."

"Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast."

Link to comment
Share on other sites

peço desculpa ... mistueia java com c++ ... tenta assim :

/// cWindowFactory.hpp
class cWindowFactory {
protected:
HINSTANCE hInstance;
map<HWND, cWindow *> windows;

public:
cWindowFactory(HINSTANCE hInstance);

cWindow * window(int width, int height); // create window
cWindow * window(HWND hwnd); // get window
};

extern cWindowFactory * factory = NULL;

/// cWindowFactory.cpp
cWindowFactory * factory = NULL;

cWindowFactory::cWindowFactory(HINSTANCE hInstance) {
this->hInstance = hInstance;
}

cWindow * cWindowFactory::window(int width, int height) {
WNDCLASS wc;

wc.style         = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc   = ::WndProc;
wc.cbClsExtra    = 0;
wc.cbWndExtra    = 0;
wc.hInstance     = this->hInstance;
wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor       = LoadCursor (NULL,IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName  = L"GLSample";
wc.lpszClassName = L"GLSample";

if(!RegisterClass(&wc)) {
	OUTPUTDEBUGTEXT("Error RegisterClass\n");
	return 0;
}

if ((hwnd = CreateWindow(L"GLSample",
                         L"Generic OpenGL Sample",
                         WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
                         CW_USEDEFAULT,
                         CW_USEDEFAULT,
                         width,
                         height,
                         NULL,
                         NULL,
                         this->hInstance,
                         NULL)) == false) {
	OUTPUTDEBUGTEXT("Error creating window!\n");
	return 0;
         }

cWindow * window = new cWindow;
window->SetHandler(hwnd);
ShowWindow(hwnd, SW_SHOWNORMAL);

this->items[hwnd] = created;

return created;
}

cWindow * cWindowFactory::window(HWND hwnd) {
return this->windows[hwnd];
}

/// main.cpp
#include <cWindowFactory.hpp>

LRESULT CALLBACK WndProc(HWND hWnd,U32 uMsg, WPARAM  wParam,LPARAM lParam) {
return factory->window(hWnd)->WndProc(hWnd, uMsg, wParam, lParam);
}

int main() {
...
factory = new cWindowFactory(hInstance);
...
        factory->window(320, 240) // create window
        ...
return 0;
}

IRC : sim, é algo que ainda existe >> #p@p
Link to comment
Share on other sites

Nao gostava de ter uma variavel global para puder controlar a windowFactory.

Agora esta a funcionar direito, so' que esta a dar erro a criar mais que uma janela.

O problema penso que seja de mandar o "this" no ultimo argumento do createwindow.

header

#ifndef cWindow_h__
#define cWindow_h__
#include <Windows.h>
#include <map>

class cSimple_Window
{
public:
cSimple_Window();
cSimple_Window(HINSTANCE hInstance);
~cSimple_Window();

virtual LRESULT msgProc(UINT msg, WPARAM wParam, LPARAM lParam);
void ProcMsg();


protected:
HINSTANCE GetInstance(){return m_hInstance;}
void SetHandler(HWND hwnd){m_hWND=hwnd;}
private:
HINSTANCE	m_hInstance;
HWND		m_hWND;

};

class cWindowFactory
{
public:

bool InitWindow();

bool InsertNewWindow(cSimple_Window *window);
void insertNewSimpleWindow();
cSimple_Window *GetWindow(HWND hWND);

void ProcWindMsg()
{
	std::map<HWND,cSimple_Window*>::iterator it;
	for(it=m_Windows.begin();it!=m_Windows.end();++it)
		it->second->ProcMsg();
}
private:
HINSTANCE	m_hInstance;
std::map<HWND,cSimple_Window*> m_Windows;
};
#endif // cWindow_h__

cpp

#include "cWindow.h"
//#include <windows.h>
#include "defines.h"


LRESULT CALLBACK
MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static cWindowFactory* app = 0;

switch( msg )
{
case WM_CREATE:
	{
		// Get the 'this' pointer we passed to CreateWindow via the lpParam parameter.
		CREATESTRUCT* cs = (CREATESTRUCT*)lParam;
		app = (cWindowFactory*)cs->lpCreateParams;
		return 0;
	}
}

// Don't start processing messages until after WM_CREATE.
if( app )
	return app->GetWindow(hwnd)->msgProc(msg, wParam, lParam);
else
	return DefWindowProc(hwnd, msg, wParam, lParam);
}

cSimple_Window::cSimple_Window()
{

}

cSimple_Window::cSimple_Window( HINSTANCE hInstance )
{

}

cSimple_Window::~cSimple_Window()
{

}

LRESULT cSimple_Window::msgProc( UINT msg, WPARAM wParam, LPARAM lParam )
{
LONG    lRet = 1; 
switch( msg )
{
	// WM_ACTIVATE is sent when the window is activated or deactivated.  
	// We pause the game when the window is deactivated and unpause it 
	// when it becomes active.  
case WM_ACTIVATE:

	return 0;

	// WM_SIZE is sent when the user resizes the window.  
case WM_SIZE:
	// Save the new client area dimensions.

	return 0;

	// WM_EXITSIZEMOVE is sent when the user grabs the resize bars.
case WM_ENTERSIZEMOVE:

	return 0;

	// WM_EXITSIZEMOVE is sent when the user releases the resize bars.
	// Here we reset everything based on the new window dimensions.
case WM_EXITSIZEMOVE:

	return 0;

	// WM_DESTROY is sent when the window is being destroyed.
case WM_DESTROY:
	PostQuitMessage(0);
	return 0;

	// The WM_MENUCHAR message is sent when a menu is active and the user presses 
	// a key that does not correspond to any mnemonic or accelerator key. 
case WM_MENUCHAR:
	// Don't beep when we alt-enter.
	return MAKELRESULT(0, MNC_CLOSE);

	// Catch this message so to prevent the window from becoming too small.
case WM_GETMINMAXINFO:
	((MINMAXINFO*)lParam)->ptMinTrackSize.x = 200;
	((MINMAXINFO*)lParam)->ptMinTrackSize.y = 200; 
	return 0;
default:
	lRet=DefWindowProc (m_hWND,msg, wParam, lParam);
	break;
}

return lRet;
}

void cSimple_Window::ProcMsg()
{
MSG msg;
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{

	TranslateMessage(&msg);
	DispatchMessage(&msg);
}
}


bool cWindowFactory::InsertNewWindow( cSimple_Window *window )
{
std::map<HWND,cSimple_Window*>::const_iterator it=m_Windows.begin();
HWND hwnd;

	if ((hwnd = CreateWindow(L"GLSample",
		L"Generic OpenGL Sample",
		WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		300,
		300,
		NULL,
		NULL,
		this->m_hInstance,
		NULL)) == false) 
	{
			OUTPUTDEBUGTEXT("Error creating window!\n");
			return 0;
	}


window->SetHandler(hwnd);
m_Windows[hwnd]=window;
ShowWindow(hwnd,SW_SHOW);
UpdateWindow(hwnd);

return true;
}

cSimple_Window * cWindowFactory::GetWindow( HWND hWND )
{
return m_Windows[hWND];
}

void cWindowFactory::insertNewSimpleWindow()
{
InsertNewWindow(new cSimple_Window);
}

bool cWindowFactory::InitWindow()
{
WNDCLASS wc;

wc.style         = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc   = ::MainWndProc;
wc.cbClsExtra    = 0;
wc.cbWndExtra    = 0;
wc.hInstance     = this->m_hInstance;
wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor       = LoadCursor (NULL,IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName  = L"GLSample";
wc.lpszClassName = L"GLSample";

if(!RegisterClass(&wc)) {
	OUTPUTDEBUGTEXT("Error RegisterClass\n");
	return 0;
}
}

Eu quero fazer isto porque vi este video e achei piada.

Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender.

A beleza de um código está em decompor problemas complexos em pequenos blocos simples.

"learn how to do it manually first, then use the wizzy tool to save time."

"Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast."

Link to comment
Share on other sites

ja criei o construtor e mandei para la' o hInstance do WinMain, mas mesmo assim, nao funciona...

Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender.

A beleza de um código está em decompor problemas complexos em pequenos blocos simples.

"learn how to do it manually first, then use the wizzy tool to save time."

"Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast."

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.