Threads



  • sarfuan: Du hast von nix ne Ahnung, hängst aber immer den Besserwisser raus. 🙄



  • "nix" bezieht sich natürlich nur auf WinAPI, das andere kann ich nicht beurteilen. 🙂



  • Ja danke für das Kompliment.

    hThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE
    MainThread,(LPVOID)hwnd,0,&dwThread);

    ist so oder so falsch. Egal ob jetzt cast oder zusätzlicher Parameter, der Compiler würde sich so oder so weigern, das zu Kompilieren. Ist es aber ein Cast und er hat es im Code richtig und nur hier falsch, dann ist auch CreateThread und der sämtliche Rest vom Code richtig und der Fehler liegt ganz woanders.

    Warum du mich so anmachst, is mir nich so ganz klar. Naja, das einzige was noch sein könnte, ist, dass es

    DWORD MainThread(LPVOID param)
    {
    return 0;
    }

    heißen müsste. Aber ich wüsste nicht, warum das mit der WndProc-Funktion im Hauptthread zusammenhängen sollte. Aber - mal ehrlich - Leute wie du regen mich auf. Ich versuch anderen zu helfen und zwar umsonst, ohne irgendeine Gegenleistung zu erwarten. Selbst ein "Danke" bekommt man so gut wie nie zu hören, das einzige was man zu hören bekommt, wenn man sich mal einen kleinen Fehler erlaubt, sind so nette Beleidigungen wie von dir.
    Da frage ich mich echt ...



  • Ich habe es mal so versucht:

    HANDLE  hThread;
    .
    .
    .
    int WINAPI WinMain(HINSTANCE hinst,...
    {
    .
    .
    .
    hThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)MainThread,
                   (LPVOID)hwnd,CREATE_SUSPENDED/*Thread nicht starten*/
                   ,&dwThread);
    
    case WM_COMMAND:
        {
            if(LOWORD(wparam) == 1)
            {
                DWORD ResumeThread((unsigned long)hThread);
            }
        }break;
    
    DWORD MainThread(LPVOID param)
    {
        WriteText(100,100,"*****TESTE*****");
        return 0;
    }
    

    Funktioniert auch nicht. Ich muss die Anwendung mit ALT+F4 beenden 😞

    Wo ist mein Fehler 😕



  • @<hans>:
    Poste mal den ganzen Code bitte. Und wenn du - wie ich bereits erwähnte - DWORD WINAPI MainThread(LPVOID param) verwendetn würdest, kannst dir den Cast auch gleich sparen (Das ist bei der Übergabe von nur einem Parameter zwar Wurst, aber ziemlich unschön trotzdem).

    Original erstellt von <MsgBox>:
    "nix" bezieht sich natürlich nur auf WinAPI, das andere kann ich nicht beurteilen. 🙂

    Ich bezweifel auch stark, dass du das eine überhaupt beurteilen kannst.



  • ich verstehe das nicht mehr 😞

    Wenn ich den Thread hier starte:

    int WINAPI WinMain( HINSTANCE hinst,HINSTANCE hprevinst,LPSTR lpcmdline,int ncmdshow)
    {
    .
    .
    .
        if (!(hwnd = CreateWindowEx(NULL,
                                    GidxClassName,
                                    GidxTitle,
                                    WS_POPUP,
                                    iSW,iSH,
                                    350,350,
                                    NULL,
                                    NULL,
                                    hinst,
                                    NULL)))return(0);
    
        //ShowCursor(false);    
        ShowWindow(hwnd,ncmdshow);
        UpdateWindow(hwnd);
    
        hThread=CreateThread(NULL,0,MainThread,
                                    (LPVOID)hwnd,0
                                    ,&dwThread);
    

    funktioniert es.

    Ich will aber das es nach einem Klick auf einen Button startet. Das macht es auch. Die Nachrichtenschleife funktioniert aber nicht mehr 😞

    Ausserdem stürzt das Programm ab wenn ich die Funktionstasten drücke.

    Hier mal der gesammte Code:

    int WINAPI WinMain( HINSTANCE hinst,HINSTANCE hprevinst,LPSTR lpcmdline,int ncmdshow)
    {
        bRunning    =TRUE;
        WNDCLASSEX  winclass;
        MSG         message;
    
        winclass.cbSize             = sizeof(WNDCLASSEX);
        winclass.style              = CS_HREDRAW | CS_VREDRAW;
        winclass.lpfnWndProc        = WinProc;
        winclass.cbClsExtra         = 0;
        winclass.cbWndExtra         = 0;
        winclass.hInstance          = hinst;
        winclass.hCursor            = LoadCursor(NULL, IDC_ARROW); 
        winclass.hbrBackground      = (HBRUSH)GetStockObject(BLACK_BRUSH);
        winclass.lpszMenuName       = NULL;
        winclass.lpszClassName      = GidxClassName;
        winclass.hIcon              = LoadIcon(NULL, IDI_APPLICATION);
        winclass.hIconSm            = LoadIcon(NULL, IDI_APPLICATION);
    
        if (!RegisterClassEx(&winclass))
        return(0);
    
        int iSW =GetSystemMetrics(SM_CXSCREEN)/2-175;
        int iSH =GetSystemMetrics(SM_CYSCREEN)/2-175;
    
        if (!(hwnd = CreateWindowEx(NULL,
                                    GidxClassName,
                                    GidxTitle,
                                    WS_POPUP,
                                    iSW,iSH,
                                    350,350,
                                    NULL,
                                    NULL,
                                    hinst,
                                    NULL)))return(0);
    
        //ShowCursor(false);    
        ShowWindow(hwnd,ncmdshow);
        UpdateWindow(hwnd);
    
        hThread=CreateThread(NULL,0,MainThread,
                                    (LPVOID)hwnd,0
                                    ,&dwThread);
    
    while (bRunning)
    {
        if(GetMessage(&message,NULL,NULL,NULL))
        {
            TranslateMessage(&message);
            DispatchMessage(&message);
        }//GetMessage
    }
    return message.wParam;  
    }//WinMain
    
    /* - - - - - - - - - - - - - - - - - - - -
        Nachrichtenberarbeitung
    - - - - - - - - - - - - - - - - - - - - */
    LRESULT CALLBACK WinProc(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam)
    {
        HWND            hwndButton;
        static HBITMAP  hBitmap ;
        static BITMAP   bitmap ;
        HDC             hdc, hdcMem;
        HINSTANCE       hInstance ;
        PAINTSTRUCT     ps ;
        /* - - - - - - - - - - - - - - - - - - - -
            Tastaturabfrage
        - - - - - - - - - - - - - - - - - - - - */
        switch(message)
        {   
            case WM_KEYDOWN:
            {
                switch(wparam)
                {
                    /* - - - - - - - - - - - - - - - - - - - -
                        Wurde ESC gedrückt. Anwendung beenden
                    - - - - - - - - - - - - - - - - - - - - */
                    case VK_ESCAPE:
                    {
                        SendMessage(hwnd,WM_DESTROY,NULL,NULL);
                    }break;
    
                    case VK_F1://Sonst stürzt das Progamm ab
                    case VK_F2:
                    case VK_F3:
                    case VK_F4:
                    case VK_F5:
                    case VK_F6:
                    case VK_F7:
                    case VK_F8:
                    case VK_F9:
                    case VK_F10:
                    case VK_F11:
                    case VK_F12:
                    {
                        return 0;
                    }break;
    
                    default:break;
                }//switch
            }
    
        /* - - - - - - - - - - - - - - - - - - - -
            Erstelle ein Button und Start-Bitmap
        - - - - - - - - - - - - - - - - - - - - */
        case WM_CREATE:
        {
            /* - - - - - - - - - - - - - - - - - - - -
                Lade Bitmap
            - - - - - - - - - - - - - - - - - - - - */
            if(!(hInstance = ((LPCREATESTRUCT) lparam)->hInstance))
                return 0;
            hBitmap = (HBITMAP) LoadImage(hInstance, "start.bmp", IMAGE_BITMAP, 0, 0,
                       LR_DEFAULTSIZE | LR_LOADFROMFILE | LR_CREATEDIBSECTION);
            GetObject (hBitmap, sizeof (BITMAP), &bitmap) ;
    
            /* - - - - - - - - - - - - - - - - - - - -
                Erstelle ein Button 
            - - - - - - - - - - - - - - - - - - - - */
            if(!(hwndButton = CreateWindow ("button", "Ok", 
                                           WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 
                                           180,310, 50, 20, 
                                           hwnd, (HMENU)1,((LPCREATESTRUCT)lparam)->hInstance, NULL)))
                                           return 0;
        }
        /* - - - - - - - - - - - - - - - - - - - -
            Prüft ob Button nr.1 gedrückt wurde
        - - - - - - - - - - - - - - - - - - - - */
        case WM_COMMAND:
        {
            if(LOWORD(wparam) == 1)
            {
                SendMessage(hwnd,WM_DESTROY,NULL,NULL);
                 /*hThread=CreateThread(NULL,0,MainThread,
                               (LPVOID)hwnd,0
                                               ,&dwThread);*/
            }
        }break;
    
        /* - - - - - - - - - - - - - - - - - - - -
            Neu zeichnen
        - - - - - - - - - - - - - - - - - - - - */
        case WM_PAINT:
        {
            /* - - - - - - - - - - - - - - - - - - - -
                Bitmap zeichnen
            - - - - - - - - - - - - - - - - - - - - */
            hdc = BeginPaint (hwnd, &ps) ;
            hdcMem = CreateCompatibleDC (hdc) ;
            SelectObject (hdcMem, hBitmap) ;
            BitBlt (hdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, hdcMem, 0, 0, SRCCOPY) ;
            DeleteDC (hdcMem) ;
            EndPaint (hwnd, &ps) ;
    
            /* - - - - - - - - - - - - - - - - - - - -
                Text ausgeben
            - - - - - - - - - - - - - - - - - - - - */
            WriteText(100,110,"****TESTE*****");          
        }break;
    
        /* - - - - - - - - - - - - - - - - - - - -
            Anwendung beenden
        - - - - - - - - - - - - - - - - - - - - */
        case WM_DESTROY: 
        {
            CloseHandle(hThread);   
            bRunning = FALSE;
            PostQuitMessage(0);
            return 1;
        } break;
    
        default:break;
        }//switch
        return (DefWindowProc(hwnd, message, wparam, lparam));
    } // WindowProc
    
    /* - - - - - - - - - - - - - - - - - - - -
        Thread
    - - - - - - - - - - - - - - - - - - - - */
    DWORD WINAPI MainThread(LPVOID param)
    {
        while(1)
        {
            DWORD time=GetTickCount();
            WriteText(100,130,"TIME: %d",time);
        }
    
        return 0;
    }
    


  • ich weiss zwar nicht woran es liegt, aber du bis doch verrückt. deine schleife zieht total rein!!! mach das nich so...



  • soll ja nur zur Übung sein 🙂



  • Hallo,

    jetzt habe ich in den Thread das eingefügt.

    DWORD WINAPI MainThread(LPVOID param)
    .
    .
    .
        MessageBox(hwnd,"Kein Strafe","Nur zur Übung",MB_OK);
    

    Nach dem die Message-Box gezeigt wird und der Thread beginnt funktioniert auch meine Nachrichtenschleife 😕

    Kann mir jemand noch sagen warum mein Programm bei benutzen der Funktionstasten abstürzt?

    Bin noch Anfänger und suche auch noch nach Quellcodes im Netzt. Wenn einer eine gute Seite mit WinApi - Code kennt bitte posten. Danke 🙂



  • Ich war nicht untätig. Ich komme trotzdem nicht weiter. Jetzt ist es schon nach drei Uhr.

    Hier noch ein paar Infos. Wenn ich den Thread starte reagiert das Programm nicht mehr auf ESC. Die Nachricht das ESC gedrückt wurde wird jedoch empfangen. Es tut sich aber nichts.
    Klicke ich auf ein anderes Fenster und wieder auf meine Anwendung kann ich das Programm wieder mit ESC beenden.

    Ich komme mit meinem Latein nicht mehr weiter. Ich hoffe ihr wisst woran es liegen könnte.



  • 1.) du musst glaub ich bRunning noch global machen
    2.) Wenn du eine Massage abfängst und bearbeitest solltest du return 0 aufrufen, ansonsten DefWindowProc
    3.) SendMessage(hwnd,WM_DESTROY,NULL,NULL); zerstört in diesem Fall den Button und nicht das Hauptfenster, oder?
    4.) Was ist WriteText?



  • 1. bRunning ist global
    2. Hab ich jetzt gemacht
    3. hwnd gehört zum Hauptfenster.
    4.

    void WriteText(int x, int y, char* text,...)
    {
        /* - - - - - - - - - - - - - - - - - - - -
        Textausgabe
        - - - - - - - - - - - - - - - - - - - - */
        HDC hdc=NULL; 
        char textBuffer[512];   
        va_list args;
        va_start(args, text);
        vsprintf(textBuffer, text, args);
        va_end(args);   
        hdc=GetDC (hwnd);
        SetTextColor(hdc,RGB(0,0,0));
        SetBkMode(hdc,TRANSPARENT);
        TextOut(hdc,x,y,textBuffer,strlen(textBuffer));
        ReleaseDC (hwnd, hdc);
    }
    

    Immer noch das gleiche Problem. Die ESC Taste und jede andere Taste wird erst verarbeitet. Wenn ich auf ein anderes Fenster klicke danach wieder auf meine Anwendung 😕



  • Noch ne Idee:
    Du startest doch mit einem Klick auf den Button den Thread -> der Button erhält den Focus
    Deshalb werden natürlich auch alle Tastendrücke an den Button weitergeleitet
    Nach dem Wechseln zu einer anderen Anwendung und wieder zurück hat wieder das Fenster den Fokus

    War nur so ne Idee. Also: versuch mal mit SetFocus nach dem Klick auf den Button den Fokus wieder auf das Hauptfenster zurückzusetzen



  • Danke 🙂

    Jetzt geht es.

    case WM_COMMAND:
            {
                switch(LOWORD(wparam))
                {
                case 1:
                    hThread=CreateThread(NULL,0,MainThread,
                                        (LPVOID)hwnd,0
                                        ,&dwThread);
                    break;
                case 2:
                    SendMessage(hwnd,WM_DESTROY,NULL,NULL);
                    break;
                }
                SetFocus(hwnd); //Fokus auf das Hauptfenster!
            }break;
    

    Bin jetzt gespannt was noch kommt 😃



  • Ach noch was. Ich habe in keiner Dokumentation gesehen das man nach WM_COMMAND den Focus auf das Hauptfenster setzen muss. Ist das OK?



  • Du solltest eben, wie schon gesagt ein return 0 ans Ende von WM_COMMAND setzen - das macht dann vielleicht auch genau das (weiß es aber net genau) 😉


Anmelden zum Antworten