mouseWheel wird nicht vererbt
-
Liebe Forenmitglieder,
ich habe ein Problem mit meiner mouseWheel- Funktion. Ich habe eine Klasse ControllerGL, die die auf einer OpenGl-Zeichenfläche abgefangenen Kommandos verarbeiten soll. Die Klasse erbt von Controller, die nur virtual- und inline- Funktionen enthält.
Diesen Contoller erhalte ich in meiner CALLBACK-Funktion mittelsGetWindowLongPtr(...)
. Der Controller soll nun in der abgefangenen Message WM_MOUSEWHEEL wie unten angedeutet auf einer Zeichenfläche etwas darstellen.
Leider ist das nicht der Fall und ich kann den Fehler einfach nicht finden zumal alles andere wie Mausbewegung oder Maustasten erfolgreich abgefangen und verarbeitet werden können. Bin für jede Hilfe dankbarmit freundlichstem Gruß
maggus----Controller.h----
{ class Controller { public: // constructor / destructor Controller(); virtual ~Controller (); virtual int mouseWheel(WPARAM wParam, int x, int y); // für WM_MOUSEWHEEL: state, x, y // und andere Funktionen, wie: virtual int lButtonUp(WPARAM state, int x, int y); // für WM_LBUTTONUP: state, x, y protected: HWND handle; }; /////////////////////////////////////////////////////////////////////////// // inline functions /////////////////////////////////////////////////////////////////////////// inline int Controller::mouseWheel(WPARAM wParam, int x, int y) { return 0; } // und andere Funktionen, wie: inline int Controller::lButtonDown(WPARAM wParam, int x, int y) { return 0; } }
----Controller.cpp----
#include "Controller.h" /////////////////////////////////////////////////////////////////////////////// // default ctor /////////////////////////////////////////////////////////////////////////////// Controller::Controller() : handle(0) { } /////////////////////////////////////////////////////////////////////////////// // dtor /////////////////////////////////////////////////////////////////////////////// Controller::~Controller() { ::PostQuitMessage(0); }
----ControllerGL.h----
class ControllerGL : public Controller { public: ControllerGL(Canvas* canvas); ~ControllerGL() {}; int mouseWheel(WPARAM state, int x, int y); int lButtonDown(WPARAM state, int x, int y); private: Canvas* canvas; }; }
----ControllerGL.cpp----
#include "ControllerGL.h" /////////////////////////////////////////////////////////////////////////////// // default contructor /////////////////////////////////////////////////////////////////////////////// ControllerGL::ControllerGL(Canvas* canvas) : canvas(canvas) { } /////////////////////////////////////////////////////////////////////////////// // verarbeite Mausrad /////////////////////////////////////////////////////////////////////////////// int ControllerGL::mouseWheel(WPARAM state, int x, int y) { canvas->setDisplayText("Endlich funktioniert's :-)"); return 0; } /////////////////////////////////////////////////////////////////////////////// // verarbeite Tastendruck /////////////////////////////////////////////////////////////////////////////// int ControllerGL::lButtonDown(WPARAM state, int x, int y) { if(state == MK_LBUTTON) { canvas->setDisplayText("Linke Maustaste wird gedrückt"); } return 0; }
----procedure.cpp----
#include "procedure.h" #include "Controller.h" LRESULT CALLBACK Win::windowProcedure(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { LRESULT returnValue = 0; // return value // finde Controller zu gegebenen Handle static Controller *ctrl; ctrl = (Controller*)::GetWindowLongPtr(hwnd, GWL_USERDATA); if(!ctrl) return ::DefWindowProc(hwnd, msg, wParam, lParam); // route messages switch(msg) { case WM_MOUSEWHEEL: returnValue = ctrl->mouseWheel(wParam , HIWORD(lParam), LOWORD(lParam)); //bis hierher klappt alles wunderbar break; case WM_LBUTTONDOWN: returnValue = ctrl->lButtonDown(wParam, LOWORD(lParam), HIWORD(lParam)); break; default: returnValue = ::DefWindowProc(hwnd, msg, wParam, lParam); } return returnValue; }
-
Zeig uns Code in dem Du GWL_USERDATA setzt!
-
Bevor das Menu und andere Clients meinem Fenster hinzugefügt werden, wird in der CALLBACK-Funktion
windowProcedure(...)
folgende Nachricht abgefangen:if(msg == WM_NCCREATE) // Non-Client Create { // WM_NCCREATE wird aufgerufen bevor Rahmen, Menu etc erzeugt werden. // Diese Nachricht führt einen Pointer auf CREATESTRUCT in lParam mit sich. // Die Member-Variable lpCreateParams von CREATESTRUCT beinhaltet dann den Wert // von lpParam von CreateWindowEx() ctrl = (Canvas*)(((CREATESTRUCT*)lParam)->lpCreateParams); ctrl->setHandle(hwnd); //der Pointer zum Controller wird folgend in GWL_USERDATA gespeichert ::SetWindowLongPtr(hwnd, GWL_USERDATA, (LONG_PTR)ctrl); return ::DefWindowProc(hwnd, msg, wParam, lParam); }
Vielen lieben Dank schonmal an Dich Martin für die ersten Denkanstöße.
Liegt hier bereits der Hund begraben? Ich werde mal Forschen
Hoffe, dass Du mir weiterhelfen kannst...mfg maggus
-
Und wo wird ctrl erzeugt?
Also was Du in lParam->lpCreateParams gespeichert hast?
-
Mein ctrl erzeuge ich in meiner main-Methode mittels:
Canvas canvas; ControllerGL glCtrl(&canvas); Window glWin(hInst, L"CanvasGL", mainWin.getHandle(), &glCtrl); glWin.setClassStyle(CS_OWNDC); glWin.setWindowStyle(WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN); glWin.create();
----window.h----
class Window { public: // ctor/dtor Window(HINSTANCE hInst, const wchar_t* name, HWND hParent, Controller* ctrl); ~Window(); HWND create(); // create a window void show(int cmdShow=SW_SHOWDEFAULT); // make the window visible HWND getHandle() { return handle; }; // return window handle int getWidth() { return width; }; int getHeight() { return height; }; // setters for WNDCLASSEX, if not specified, use default values void setClassStyle(UINT style) { winClass.style = style; }; void setIcon(int id) { winClass.hIcon = loadIcon(id); }; void setIconSmall(int id) { winClass.hIconSm = loadIcon(id); }; void setCursor(int id) { winClass.hCursor = loadCursor(id); }; void setBackground(int color) { winClass.hbrBackground = (HBRUSH)::GetStockObject(color); }; void setMenuName(LPCTSTR name) { winClass.lpszMenuName = name; }; // setters for CreateWindowEx() void setWindowStyle(DWORD style) { winStyle = style; }; void setWindowStyleEx(DWORD style) { winStyleEx = style; }; void setPosition(int x, int y) { this->x = x; this->y = y; }; void setWidth(int w) { width = w; }; void setHeight(int h) { height = h; }; void setParent(HWND handle) { parentHandle = handle; }; void setMenu(HMENU handle) { menuHandle = handle; }; private: enum { MAX_STRING = 256 }; // local constants, max length of string // member functions void registerClass(); // register window class with Windows system HICON loadIcon(int id); // load icon using resource id HCURSOR loadCursor(int id); // load icon using resource id HWND handle; // handle to this window WNDCLASSEX winClass; // window class information DWORD winStyle; // window style: WS_OVERLAPPEDWINDOW, WS_CHILD, ... DWORD winStyleEx; // extended window style wchar_t title[MAX_STRING]; // title of window wchar_t className[MAX_STRING]; // name of window class int x; // window position X int y; // window position Y int width; // window width int height; // window height HWND parentHandle; // handle to parent window HMENU menuHandle; // handle to menu HINSTANCE instance; // handle to instance Controller *controller; // pointer to controller }; }
----window.cpp---- #include <sstream> #include <iostream> #include <cstring> #include "Window.h" #include "procedure.h" using std::wstringstream; using std::wcout; using std::endl; Window::Window(HINSTANCE hInst, const wchar_t* name, HWND hParent, Controller* ctrl) : handle(0), instance(hInst), controller(ctrl), winStyle(WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN), winStyleEx(WS_EX_CLIENTEDGE), x(CW_USEDEFAULT), y(CW_USEDEFAULT), width(CW_USEDEFAULT), height(CW_USEDEFAULT), parentHandle(hParent), menuHandle(0) { // copy string wcsncpy(this->title, name, MAX_STRING-1); wcsncpy(this->className, name, MAX_STRING-1); // populate window class struct winClass.cbSize = sizeof(WNDCLASSEX); winClass.style = 0; winClass.lpfnWndProc = windowProcedure; // pointer to window procedure winClass.cbClsExtra = 0; winClass.cbWndExtra = 0; winClass.hInstance = instance; winClass.hIcon = LoadIcon(0, IDI_APPLICATION); winClass.hCursor = LoadCursor(0, IDC_ARROW); winClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); winClass.lpszMenuName = 0; winClass.lpszClassName = className; winClass.hIconSm = LoadIcon(0, IDI_APPLICATION); } /////////////////////////////////////////////////////////////////////////////// // destructor /////////////////////////////////////////////////////////////////////////////// Window::~Window() { ::UnregisterClass(className, instance); } /////////////////////////////////////////////////////////////////////////////// // create a window /////////////////////////////////////////////////////////////////////////////// HWND Window::create() { // register a window class if(!::RegisterClassEx(&winClass)) return 0; handle = ::CreateWindowEx(winStyleEx, // window border with a sunken edge className, // name of a registered window class title, // caption of window winStyle, // window style x, // x position y, // y position width, // witdh height, // height parentHandle, // handle to parent window menuHandle, // handle to menu instance, // application instance (LPVOID)controller); // window creation data //this->show(SW_SHOWDEFAULT); // make it visible return handle; } { ::ShowWindow(handle, cmdShow); ::UpdateWindow(handle); } /////////////////////////////////////////////////////////////////////////////// // load an icon using resource ID and convert it to HICON /////////////////////////////////////////////////////////////////////////////// HICON Window::loadIcon(int id) { return (HICON)::LoadImage(instance, MAKEINTRESOURCE(id), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE); } /////////////////////////////////////////////////////////////////////////////// // load an icon using resource ID and convert it to HICON /////////////////////////////////////////////////////////////////////////////// HICON Window::loadCursor(int id) { return (HCURSOR)::LoadImage(instance, MAKEINTRESOURCE(id), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE); }
-
Das Problem besteht leider noch weiterhin. Ich poste auch gerne noch mehr Code, wenn es nötig ist. Bin für jeden Tip dankbar.
mfg maggus