SendMessage bei ProgressBar als Klasse in DLL



  • Da dies mein erster Beitrag in diesem Forum ist, erstmal ein Hallo an alle. 😉 Und wie jeder Neuling werde ich damit anfangen eine Frage zu stellen... 😛

    Ich versuche momentan eine einfache DLL zu erstellen, mithilfe derer man eine ProgressBar verwalten kann. Dafür habe ich in dieser DLL eine Klasse erstellt, in welcher bei Aufruf des Konstruktors ein Fenster mit einer ProgressBar und einem Cancel-Button erstellt wird.
    Innerhalb der Methode Initiate() läuft eine Message Loop.

    Mein Problem besteht momentan in der Implementierung der Methode inc() dieser Klasse, welche den Fortschrittsbalken vergrößern soll.
    Die versendete Message PBM_STEPIT kommt aus irgendeinem Grund nicht bei der ProgressBar an.
    Da ich mich erst seit vorgestern mit der WinAPI und DLL's beschäftige, fehlt mir leider das nötige Hintergrundwissen über den Ablauf der gesamten Struktur. Da SendMessage anscheinend die Prozedur des jeweiligen Windows direkt ansteuert (und nicht den Umweg über die Loop geht) und die Verwaltungsprozedur der Klasse PROGRESS_CLASS nicht einsehbar ist, weiß ich nicht weiter.
    Durch irgendetwas scheint die Message nicht anzukommen.

    €: Um das auszuschließen: Die Prozedur inc() wird bei Klicken des Buttons problemlos aufgerufen, sendmessage erfolgt auch, geht aber ins Nirvana.

    Wie kann ich eine Message unter den oben genannten Bedingungen an meine PROGRESS_CLASS schicken?

    Deklaration der Klasse:

    class DLL_EXPORT CENProgressBar {
    
        //Funktion des erstellten Windows
        friend LRESULT CALLBACK pbarProc(HWND hwnd,UINT msg,WPARAM wParam, LPARAM lParam);
    private:
        HWND m_winHWND;        //Handle des Hauptfensters
        HWND m_pbarHWND;       //Handle der erstellten ProgressBar
        HWND m_cReceiverHWND;  //Input-Handle zum senden einer Message bei 
                               //Betätigung des Cancel-Buttons
    
        HINSTANCE m_hInstance; //Fensterinstanz (habe ich noch Verständnisprobleme)
    
        int m_currStep;        //aktuelle Position der ProgressBar
    
    public:
    //Im Konstruktor wird übergeordnetes Fenster ("Hauptfenster") erstellt und in m_winHWND abgespeichert
    //alle anderen Member außer m_pbarHWND werden dort durch einfache Zuweisung initialisiert
        CENProgressBar(HINSTANCE hInstance,int nCmdShow ,HWND cancelReceiver);
        ~CENProgressBar();
    
        void inc(int step = 10);
        void setPos(int newPos);
        void Initiate();
    
        int getPos();
    };
    

    Implementierung Initiate:

    void CENProgressBar::Initiate() {
        MSG msg;
        while (GetMessage(&msg,NULL,0,0) > 0) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    

    Window-Funktion (Ausschnitt):

    LRESULT CALLBACK pbarProc(HWND hwnd,UINT msg,WPARAM wParam, LPARAM lParam) {
        switch (msg) {
        case WM_CREATE:
            ...
    
            INITCOMMONCONTROLSEX comCtrls;
            comCtrls.dwSize = sizeof(INITCOMMONCONTROLSEX);
            comCtrls.dwICC = ICC_PROGRESS_CLASS;
            InitCommonControlsEx(&comCtrls);
    
            //obj ist ein Pointer auf die aktuelle Klasse (im Konstruktor durch this-Zeiger gewonnen)
            obj->m_pbarHWND = CreateWindowEx(0,PROGRESS_CLASS,"",WS_CHILD | WS_VISIBLE,0,0,130,30,hwnd,NULL,reinterpret_cast<LPCREATESTRUCT>(lParam)->hInstance,NULL);
    
            if (obj->m_pbarHWND = NULL) {
            ...
            }
    
            return DefWindowProc(hwnd,msg,wParam,lParam);
        case WM_COMMAND:
            switch (LOWORD(wParam)) {
            case IDCANCEL:
                if (obj->m_cReceiverHWND != NULL) {
                    SendMessage(obj->m_cReceiverHWND, PBAR_ABORT, 0, 0);
                }
                break;
            }
            break;
        ...
        }
        return 0;
    }
    

    Implementierung Inc:

    void CENProgressBar::inc(int step) {
        if (step != m_currStep) {
            SendMessage(m_pbarHWND,PBM_SETSTEP, step,0);
            m_currStep = step;
        }
        SendMessage(m_pbarHWND, PBM_STEPIT, 0, 0);
    }
    

    Ausschnitt der Window-Procedure des Test-Programms (nur zum testen, deshalb unsauber)
    IDYES wird für das Inkrementieren verwendet, nicht Verwirren lassen. 😛

    LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
        switch (msg) {
        case WM_CREATE:
            //Button zum Erstellen eines Objekts der Klasse
            CreateWindow(TEXT("Button"),"Start!",
                         WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                         50,50,50,50,
                         hwnd,
                         (HMENU)IDOK,
                         ((LPCREATESTRUCT)lParam)->hInstance,
                         NULL);
            //Button zum Inkrementieren des Wertes
            CreateWindow(TEXT("Button"),"Increase!",
                         WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                         10,10,20,20,
                         hwnd,
                         (HMENU)IDYES,
                         ((LPCREATESTRUCT)lParam)->hInstance,
                         NULL);
            return DefWindowProc(hwnd,msg,wParam,lParam);
            break;
        case WM_COMMAND:
            switch (LOWORD(wParam)) {
            case IDOK: //(Erstellen)
                hinstLib = LoadLibrary("pbar.dll");
                if (hinstLib) {
                    //newProgressBar entspricht "new CENProgressBar"
                    //pb ist ein globaler void-Pointer
                    pb = (CENProgressBar*)newProgressBar(hInst,SW_SHOWDEFAULT,hwnd);
                    reinterpret_cast<CENProgressBar*>(pb)->Initiate();
                }
                break;
            case IDYES: //(Inkrementieren)
                reinterpret_cast<CENProgressBar*>(pb)->inc();
                break;
            }
            break;
        ...
        }
        return 0;
    }
    

    Ich hoffe ich habe nichts Wichtiges vergessen..
    Vielen Dank schonmal im Voraus!



  • Ich habe nochmal versucht, ein bisschen mehr in meinem Code auszukommentieren, aber es sind eigentlich alles Standardfunktionen, ich weiß nicht, was ich noch groß erklären soll...

    Ich weiß, dass es anstrengend ist, sich mit so einem Codebatzen zu beschäftigen und zu versuchen den Fehler zu finden, aber es wäre dennoch nett, wenn sich jemand die Zeit nehmen würde.

    Wie gesagt, es gibt keine Compiler-Fehlermeldungen und auch das Programm läuft wunderbar. Durch drücken auf "Start" wird Progressbar geöffnet, bei Druck auf "Cancel" innerhalb der Progressbar, wird diese geschlossen. Während sie geöffnet ist, fängt die Messageloop der Progressbar alle Nachrichten ab und verteilt sie.

    Ich würde gerne mehr Informationen geben, aber leider fehlen mir an der Stelle noch gewisse grundlegende Kenntisse. Wenn eine relevante Information fehlt, bitte mitteilen.

    Danke.



  • ich sehs jetzt hier drin nicht, deshalb frag ich mal:
    hast du vorher pbm_setrange hingeschickt?



  • Nein, habe ich nicht. Allerdings hat es in kleineren Testprogrammen auch ohne SetRange funktioniert, könnte dort trotzdem eine Ursache liegen?



  • kann schon sein ich würds zur sicherheit mal reinmachen



  • Hab's reingemacht, keine Veränderung. Kann leider nicht überprüfen, ob das funktioniert hat, da es ja nicht sichtbar für den Anwender ist, aber ich gehe davon aus, dass diese Message ebenfalls im Nirvana gelandet ist.



  • Ich habe festgestellt, dass das Handle m_pbarHWND NULL ist, wenn es in inc() ankommt. Nach der Zuweisung ist es dies allerdings noch nicht (wird ja auch überprüft)

    Wenn ich obj->m_pbarHWND abfrage, ist dies auch NULL, es liegt also nicht an dem zusätzlichen Zeiger (bzw. es ist immer die gleiche Instanz).

    Hat jemand eine Idee, woran das liegen könnte?

    Danke.



  • if (obj->m_pbarHWND = NULL) {
            ...
            }
    

    ->

    if (obj->m_pbarHWND == NULL) {
            ...
            }
    

    Hast ein = vergessen. Wenn du selbst NULL zuweißt, darfste dich nicht wundern, wenn da auch NULL dann rauskommt. 😉

    greetz KN4CK3R



  • Ich wollte es gerade ins Forum schreiben...

    Trotzdem vielen Dank!

    AAH! 3 Tage Fehlersuche, verdammt!! ^^



  • helf mir zum Ausgleich hier
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-239194.html
    und ich bin auch glücklich. 😉

    greetz KN4CK3R


  • Mod

    if (obj->m_pbarHWND = NULL) { 
            ... 
            }
    

    Mit /W4 wäre das nicht passiert, auch nicht mit

    if (NULL = obj->m_pbarHWND) { 
            ... 
            }
    

    Schreibe die Konstante zum Vergleich links und der Tippfehler endet in einem Compiler-Fehler.


Anmelden zum Antworten