// this will be WNDCLASSEX::lpfnWndProc LRESULT CALLBACK BaseWindow::msgRouter (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ //pointer to the window that will receive the message BaseWindow *wnd = 0; if(message == WM_NCCREATE){ // receiving a WM_NCCREATE message means that a new window has just been created, // so we need to associate the window's handle with its BaseWindow instance pointer SetWindowLong(hWnd, GWL_USERDATA, long((LPCREATESTRUCT(lParam))->lpCreateParams)); } // we retrieve the instance of AbstractWindow that corresponds to the destination window's HWND wnd = (BaseWindow*) (GetWindowLong (hWnd, GWL_USERDATA)); // we then route the message to the wndProc method defined in the derived BaseWindow class if (wnd) return wnd->wndProc(hWnd, message, wParam, lParam); else // for messages that arrive prior to WM_NCCREATE // and the HWND <-> BaseWindow * association was not made return DefWindowProc(hWnd, message, wParam, lParam); }
LRESULT CALLBACK BaseWindow::baseWndProc(HWND hwnd, UINT mess, WPARAM wParam, LPARAM lParam) { BaseWindow *instance = NULL; BaseWindow *childInstance = NULL; if ( mess == WM_CREATE ) { //ottengo il puntatore this CREATESTRUCT *cStruct = (CREATESTRUCT*)lParam; instance = (BaseWindow*)cStruct->lpCreateParams; if ( instance ) //salvo il puntatore nello spazio utente della window SetWindowLongPtr(hwnd,GWLP_USERDATA, (LONG_PTR)instance); return TRUE; } else { //verifico la notifica di un child if ( mess == NOTIFY_CHILD_CREATION ) { //un child notifica la propria creazione HWND tmpHwnd = (HWND)wParam; childInstance = (BaseWindow*)lParam; if ( childInstance && tmpHwnd ) { //salvo il this sullo spazio utente della hwnd SetWindowLongPtr(tmpHwnd, GWLP_USERDATA, (LONG_PTR)childInstance); } } else if ( mess == WM_COMMAND || mess == WM_HSCROLL || mess == WM_VSCROLL ) { instance = BaseWindow::getInstance((HWND)lParam); } else if ( mess == WM_NOTIFY ) { LPNMHDR data = (LPNMHDR)lParam; instance = BaseWindow::getInstance(data->hwndFrom); } else if ( mess == WM_MENUCOMMAND ) { //messaggio da un menu con MF_BYPOSITION HMENU menu = (HMENU)lParam; MENUINFO info; memset(&info,0,sizeof(MENUINFO)); info.fMask = MIM_MENUDATA; info.cbSize = sizeof(MENUINFO); GetMenuInfo(menu,&info); instance = (BaseWindow*)info.dwMenuData; } /*else if ( mess == WM_CLOSE ) { instance = BaseWindow::getInstance(hwnd); if ( instance && instance->closeList ) return instance->closeList->onClose(instance->idWin, instance->getHWND()); } */ else instance = BaseWindow::getInstance(hwnd); if ( instance ) return instance->wndProc(mess, wParam, lParam); else return DefWindowProc(hwnd, mess, wParam, lParam); } }