wieso bleib ich hier im messageloop hängen?



  • also,mein programm bleibt in der nachrichten verarbeitung einfach stecken, die nachrichten werden zwar verarbeitet, ich hab das getestet, wenn ich in BUTTON das programm beenden lasse wenn die WM_LBUTTONUP message kommt, dann beendet das programm korrekt, also die nachrichten werden verarbeitet
    ich hab zuwenig erfahrung mit der winapi um zu wissen, woran es liegen kann, vielleicht könnt ihr euch das mal anschauen...

    also, so sieht die main aus:

    WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
        Windows::Form parent("hallo",100,100,800,600);
        parent.CreateButton("hallo",100,100,100,100);
        MSG message;
        while(GetMessage(&message,0,0,0)){
            TranslateMessage(&message);
            DispatchMessage(&message);
        }
        return 0;
    }
    

    zur info: das programm erstellt ein fenster, und schreibt einen button in die mitte.

    so sieht die dazugehörige .h,hab sie heute mal zum lernen der winapi erstellt:

    namespace Windows{
        typedef long(__stdcall *callback)(void*,unsigned int,unsigned int,long);
    ////////////////////////////////SUBCLASS///////////////////////////////////////
    //this class is used for creating subclasses.Classes should inherit from it  //
    ///////////////////////////////////////////////////////////////////////////////
        class SubClass{
            private:
                callback oldCallback;
                HWND subclass;
            protected:
                SubClass(){}
                HWND subClass(HWND window,callback newCallback,SubClass* pointer){
                    subclass=window;
                    oldCallback=reinterpret_cast<callback>(SetWindowLongPtr(subclass,GWL_WNDPROC,reinterpret_cast<long>(newCallback)));
                    SetProp(subclass,"classPointer",pointer);
                    SetProp(subclass,"oldCallback",oldCallback);
                    return subclass;
                }
                virtual ~SubClass(){
                    RemoveProp(subclass,"classPointer");
                    RemoveProp(subclass,"oldCallback");
                    SetWindowLongPtr(subclass,GWL_WNDPROC,reinterpret_cast<long>(oldCallback));
                }
        };
    
    ///////////////////////////////BUTTON//////////////////////////////////////////
    //the simple push Button,if you want to check whether the button is clicked  //
    //or not, use isClicked                                                      //
    /////////////////////////////////////////////////////////////////////////////// 
        class Button:public SubClass{
            private:
                //new callback
                static long __stdcall windowProc(void* hwnd,unsigned int message,unsigned int wParam,long lParam){
                    Button* button=reinterpret_cast<Button*>(GetProp(hwnd,"classPointer"));
                    callback oldCallback=reinterpret_cast<callback>(GetProp(hwnd,"oldCallback"));
    
                    if(message==WM_LBUTTONUP){
                        button->clicked=true;
                        //das hier drunter funktioniert, die messages kommen also an
                        //atm deaktiviert
                        //SendMessage(button->parent,WM_CLOSE,0,0);
                    }
                    return(oldCallback(hwnd,message,wParam,lParam));
                }
    
                bool clicked;
                HWND window;
                HWND parent;
            public:
                Button(HWND windowParent,std::string label,int posX,int posY,int width,int height,int ID):parent(windowParent),clicked(false){
                    HWND temp=CreateWindow("BUTTON",label.c_str(),WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,posX,posY,width,height,parent,reinterpret_cast<HMENU>(ID),GetModuleHandle(NULL),0);
                    window=subClass(temp,windowProc,this);
                }
                bool isClicked(){
                    bool temp=clicked;
                    clicked=false;
                    return temp;
                }
        };
    //////////////////////////////////FORM//////////////////////////////////////////
        class Form{
            private:
                HWND windowHandle;
                std::vector<SubClass*> childWindows;
            public:
                Form(std::string name,int topleftX,int topleftY,int width,int height);
                ~Form(){
                    childWindows.erase(childWindows.begin(),childWindows.end());
                    DestroyWindow(windowHandle);
                }
                Button* CreateButton(std::string label,int posX,int posY,int width,int height){
                    childWindows.push_back(new Button(windowHandle,label,posX,posY,width,height,childWindows.size()));
                    return dynamic_cast<Button*>(childWindows.back());
                }
                HWND getHandle(){
                    return windowHandle;
                }
        };
    }
    

    //edit fals ihr das problem auf anhieb lösen könnt: gibts innerhalb der msdn eine allgemeine kurzübersicht über alle klassen die von windowcreate erstellt werden könne(zb progressbar),und die anchrichten, die sie erhalten(senden können?unter WindowCreate steht in der msdn leider nur ein teil 😞



  • Wenn die Nachrichten verarbeitet werden ist doch alles okay. Was willst du mehr?



  • aus dem messageloop kommen damit ich "ausserhalb" auf die ergebnisse der nachrichten reagieren kann?



  • Ne, da hast du was falsch verstanden. Man muss die ganzen Zeit in dieser Schleife sein.



  • muss ich das? und was ist zb mit dem code hier?(hab ihn der einfachheit halber einfach mal von zfx.info kopeirt und gekürzt)

    while (!blnBeenden) {
       // Ist eine Nachricht zu verarbeiten?
       while(GetMessage(&message,NULL,0,0)) { 
          TranslateMessage(&message);
          DispatchMessage(&message);
       }
    
       switch(Spiel_Zustand){
           //uninteressant  
       }
    }
    

    wieso geht das da, und bei meinem code nicht?



  • Wenn du das willst, nimm PeekMessage statt GetMessage



  • jo, damit gehts, danke 🙂



  • PeekMessage würd ich nicht nehmen denn ich glaub das lastet deine CPU 100% aus. Wie wärs mit PostQuitMessage(0); oder so?



  • nein, postquitmessage war nur zum testen ob nachrichten verarbeitet werden, ansich ging es aber darum, auf nachrichten ausserhalb des messageloops reagieren zu können, zb sowas:

    {
        Windows::Form parent("hallo",100,100,300,300);
        Windows::Button* button=parent.CreateButton("close",100,100,100,100);
        MSG message;
        bool doContinue=true;
        while(doContinue){
            while(PeekMessage(&message, NULL, 0, 0, PM_REMOVE)){
                TranslateMessage(&message);
                DispatchMessage(&message);
            }
            if(button->isClicked()){
                button->destroy();
                doContinue=false;
            }
        }
        return 0;
    }
    

Log in to reply