pikax Posted April 5, 2012 Report Share Posted April 5, 2012 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 More sharing options...
HappyHippyHippo Posted April 5, 2012 Report Share Posted April 5, 2012 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 Portugol Plus Link to comment Share on other sites More sharing options...
pikax Posted April 5, 2012 Author Report Share Posted April 5, 2012 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 More sharing options...
HappyHippyHippo Posted April 5, 2012 Report Share Posted April 5, 2012 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 Portugol Plus Link to comment Share on other sites More sharing options...
pikax Posted April 6, 2012 Author Report Share Posted April 6, 2012 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" 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 More sharing options...
HappyHippyHippo Posted April 6, 2012 Report Share Posted April 6, 2012 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 Portugol Plus Link to comment Share on other sites More sharing options...
pikax Posted April 12, 2012 Author Report Share Posted April 12, 2012 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 More sharing options...
HappyHippyHippo Posted April 12, 2012 Report Share Posted April 12, 2012 então rapaz !!! não tens construtor da factory a receber o valor a ser atribuido ao parâmetro interno da classe m_hInstance !!! é por isso que o valor do this->m_hInstance é "lixo" e rejeitado pela função CreateWindow ... IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Link to comment Share on other sites More sharing options...
pikax Posted April 12, 2012 Author Report Share Posted April 12, 2012 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 More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now