callback, wa ist das?



  • Beispiel-Code ist in Delphi, aber sollte trotzdem verständlich sein:
    http://www.michael-puff.de/Developer/Artikel/2006_03/Callback.shtml



  • Ich hab folgendes in meiner Hudmanager/hud Klasse implementiert. Der thread eignet sich vielleicht ganz gut mal nen Kommentar einzufangen. War mir nämlich garnicht sicher ob das so halbwegs gut gelöst ist.

    Programmablauf:
    Hud erstellen, mit callback function initialisieren und dann in den container stecken. Irgendwann dann noch rendern.

    //application.cpp
    Hud* TestHud = new Hud("TestHud");         //der neue hud heisst TestHud
    TestHud->SetRenderCallBack(HudsOnRender);  //set the callback func
    
    Hudmanager * Manager = new HudManager();   //HudManager (set of Huds), übernimmt rendern etc.
    Manager->Add(TestHud);  //Hud in diesem Container registrieren
    
    ....
    
    void GLRender(){
       Manager->render();   //der hud manager übernimmt das rendern
    }
    

    So sieht die function aus die den callback registriert. Natürlich member von class Hud

    //hud.h
    void SetRenderCallBack(void (*func)(Hud * thehud)){mpRenderFunc = func;};
    

    Der HudContainer/Manager, iteriert durch all seine huds und ruft vor dem rendern ggfs. die CallBackfunction auf.

    //hudmanager.cpp
    void HudManager::render(){
    
    	std::vector<Hud*>::iterator it;
    	for (it=Huds.begin();it<Huds.end();it++){
    		if((*it)->mpRenderFunc != NULL)
    			(*it)->mpRenderFunc(*it); //called just before the hud is rendered, for updates etc.
    
    		(*it)->render();
       }
    
    }
    

    Das hier ist wieder im Hauptprogramm die Callback function die vom manager kurz vor dem Rendern aufgerufen wurde. Zeiger zum Hud Objekt kommt natürlich mitgeliefert.

    //application.cpp
    void HudsOnRender(Hud * thehud){
    	if(thehud->getName() == "TestHud"){
                //react to render event, change dynamicly changing values or whatever.
    	}
    }
    

    Könnt ihr dass so absegnen oder ist das "Thema verfehlt, setzen, 6!"?



  • @GreyHound: Ist zwar gut, dass Du den Code 'aufs Wesentliche' reduziert hast, aber das ist etwas sehr wesentlich 😉 . Gibt mal ein paar Infos dazu, da fehlt mir irgendwie der Kontext.



  • Habs dir nochmal ein bisschen kommentiert. Es geht mir ja eher ums Prinzip, das sollte man doch recht schnell erkennen können denke ich. Der Code ansich gefällt mir ganz gut so und funktioniert auch tadellos.

    😉 Dachte das der Code recht easy zu lesen ist. Btw. der ist nicht beschnitten, der läuft genau so.

    Bin mir nur nicht sicher ob dass mit meinen Callbacks so recht ok ist oder ob man für dass was ich da mache nen andern Begriff verwendet. (Weil die Huds ja zum beispiel nicht selber für den call sorgen etc.)

    Selbst find ichs eigendlich ganz hübsch so, is halt mein erster Versuch deswegen interessieren mich andere Meinungen darüber. Hab praktisch genau das gleiche auch für MouseMove/MouseClock etc. um HoverEffects zu rendern und zeugs auszuführen wenn man drauf clickt.

    Das sieht dann halt dementsprechend so aus

    void App::MouseClick(int x, int y, int button){
    Hudmanager->Click(int x, int y, int button);
    }
    

    Der iteriert dann wieder du seine member, schaut nach mouseover und ruft dann ggfs. wieder ne Methode auf

    OnMouseClick(Hud * theHud){//handle stuff}
    


  • hmm trifft sich gut,
    hab bezüglich callbacks auch ne frage.

    generell weis ich ja wie es funzt und wofür sie gut sind. in Dialogfenstern die mit CreateDialog aufgerufen werden klappt das immer auf anhieb.

    Jedoch wenn ich mir zB ne Callback funktion für eine eigene Classe TabCtrl, EditCtrl, Trackbar Ctrl usw. innerhalb eines Dialoges erstellen will die mit CreateWindow o. CreateWindowEx erstellt wurden, bekomm ich entweder die CallBack nicht zum laufen, oder aber sie läuft aber das Control wird nicht mehr angezeigt.

    der code den ich dafür versuche zu verwenden ist eigendlich nur

    HWND hWnd = CreateWindow(	.......);
    SetWindowLong(hWnd, GWL_WNDPROC, (LONG) CtrlProc);
    
    LRESULT APIENTRY  CtrlProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
    
    bzw.
    
    BOOL CALLBACK  CtrlProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
    

    kann mir da jemand weiterhelfen?
    ich bräuchte callback funktionen für Controls (Edit, Combobox, TabCtrl Slider usw...) die mit CreateWindow(Ex) erstellt wurden.

    oder was mach ich falsch??

    mfg
    artifact



  • CreateWindowEx enthält keinen Übergabeparameter für eine Callback. Nimm stattdessen CreateDialog() für nicht-modale Dialoge oder DialogBox() (für modale Dialoge), oder Du mußt eine neue Fensterklasse per RegisterClassEx() anlegen. Die Callback-Funktion wird im Parameter WNDCLASS.lpfnWndProc angegeben.



  • hmm,
    hab das jetzt mal mit RegisterClassEx() probiert. mit dem gleichen ergebniss, das Control wird nicht mehr angezeigt.

    Registrieren tu ich so

    WNDCLASSEX wcex;
    
    //GetParent() Handle auf das DialogFenster
    HINSTANCE hInstance = (HINSTANCE) GetWindowLong(GetParent(),GWL_HINSTANCE);
    
    wcex.cbSize		= sizeof(WNDCLASSEX); 
    wcex.style		= CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc		= (WNDPROC)CtrlProc;
    wcex.cbClsExtra		= 0;
    wcex.cbWndExtra		= 0;
    wcex.hInstance		= hInstance;
    wcex.hIcon		= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MAINICON));
    wcex.hCursor		= LoadCursor(NULL, IDC_WAIT);
    wcex.hbrBackground		= (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName		= NULL;
    wcex.lpszClassName		= "MeinControl";
    wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_MAINICON));
    
    RegisterClassEx(&wcex)
    

    die callback funktion starten mach ich so.

    //hWndCtrl Handle auf das Control (Edit, Combobox, Tab, Slider usw...)
    SetWindowLong(hWndCtrl, GWL_WNDPROC, (LONG) CtrlProc);
    

    und die callback funktion sieht so aus

    BOOL CALLBACK CtrlProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
    
    return DefWindowProc(hDlg, message, wParam, lParam);
    }
    

    😕
    was mach ich falsch??



  • Was Du machen willst, ist offensichtlich ein ChildWindow in Gestalt eines Dialogs.
    Ein mit RegisterClassEx registriertes Fenster rufst Du - zusätzlich zu Deinem Hauptfenster- in der WndProc mit

    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    static HWND hCtrl;
    
    hCtrl = CreateWindowEx()
    

    auf. Finde ich bei Dir nirgends.
    Das

    SetWindowLong(hWndCtrl, GWL_WNDPROC, (LONG) CtrlProc);
    

    kannst Du weglassen, da die CtrlProc schon in der Wndclass-Struktur festgelegt ist.

    Hier mal ein Tutorial zu ChildWindows: ➡ http://www.win-api.de/tutorials.php?tutid=12



  • INT_PTR CALLBACK CtrlProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); ist die korrekte Typisierung für eine Dialog-Prozedur.

    @GreyHound: Ist okay, kannst Du so machen 😉 .



  • Ups vergessen: @@rT!f@Ct: Oder willst Du subclassen?


Anmelden zum Antworten