Nachrichten Trotz schleife?



  • Ich habe hier folgendes getest:

    #include <windows.h>
    
    long CALLBACK WndProc(HWND, UINT, UINT, LONG);
    void move(int);
    
    MSG messages;
    char szClassName[ ] = "Test 1.0";
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil)
    {
      HWND hwnd;
      /* Fenster Handle */
      WNDCLASSEX wincl;
      wincl.hInstance = hInstance;
      wincl.lpszClassName = szClassName;
      wincl.lpfnWndProc = WndProc;
      wincl.style = CS_DBLCLKS;
      wincl.cbSize = sizeof(WNDCLASSEX);
      wincl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
      wincl.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
      wincl.hCursor = LoadCursor(NULL, IDC_ARROW);
      wincl.lpszMenuName = NULL;
      wincl.cbClsExtra = 0;
      wincl.cbWndExtra = 0;
      wincl.hbrBackground = (HBRUSH) GetStockObject(LTGRAY_BRUSH);
    
      if(!RegisterClassEx(&wincl))
         return 0;
    
        hwnd = CreateWindowEx(0,szClassName,"Test 1.0",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,400,300,HWND_DESKTOP,NULL,hInstance,NULL );
    
        ShowWindow(hwnd, SW_HIDE);
    
        HICON hProgramIcon;
        NOTIFYICONDATA nidTrayIcon;
    
        hProgramIcon = (HICON)LoadImage (hInstance, "icon.ico", IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
    
        ///////////////////////////////////////////////////////
        //Create Tray Icon
        char szTip[64] = "Test 1.0"; //Exemplarisch
    
        nidTrayIcon.cbSize = sizeof(nidTrayIcon); 
        nidTrayIcon.hIcon = hProgramIcon; //Exemplarisch 
        nidTrayIcon.hWnd = hwnd; //Exemplarisch, HWND des Fensters an dessen MessageLoop die Nachricht geschickt werden soll
        nidTrayIcon.uCallbackMessage = (WM_USER + 1); //Exemplarisch 
        nidTrayIcon.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; //Exemplarisch 
        nidTrayIcon.uID = 0x0200; //Exemplarisch 
    
        strcpy(nidTrayIcon.szTip, szTip); 
        nidTrayIcon.szTip[strlen(szTip)] = '\0'; 
    
        Shell_NotifyIcon(NIM_ADD, &nidTrayIcon);
        ///////////////////////////////////////////////////////
    
      while(GetMessage(&messages, NULL, 0, 0)) DispatchMessage(&messages);
    
      return messages.wParam;
    }
    
    long CALLBACK WndProc(HWND hWnd, UINT nMsg, UINT wParam, LONG lParam) 
    { 
       POINT pt; 
    
       switch(nMsg) 
       { 
       case (WM_USER + 1): 
          { 
             switch(lParam) 
             { 
                case WM_RBUTTONUP:
                {
                  static HMENU hMenu;
                  hMenu = CreatePopupMenu (); // Menu anlegen
                  InsertMenu (hMenu, 0, MF_BYPOSITION, 0, "Start");
                  InsertMenu (hMenu, 1, MF_BYPOSITION, 1, "Stop");
                  InsertMenu (hMenu, 2, MF_SEPARATOR,  0, NULL); // Separator
                  InsertMenu (hMenu, 3, MF_BYPOSITION, 3, "Beenden");
    
                  SetForegroundWindow(hWnd);
                  GetCursorPos(&pt);
                  int iAuswahl = (int) TrackPopupMenu (hMenu, TPM_CENTERALIGN | TPM_LEFTBUTTON |TPM_RETURNCMD, pt.x, pt.y, 0, hWnd, 0);
                  PostMessage(hWnd, WM_NULL, 0, 0);
    
                   if (iAuswahl == 0)
                       //Start
                   if (iAuswahl == 1)
                       //Stop
                   if (iAuswahl == 3)
                       PostQuitMessage(0);
                } 
             } 
    
             return 0; 
          } 
    
       default: 
          return DefWindowProc(hWnd, nMsg, wParam, lParam); 
       } 
    }
    

    So jetzt habe ich ein schönes TrayIcon was auch gut Funktioniert. Jetzt sollte einfach ne simple schleife ablaufen wenn ich auf start drücke und wenn ich auf stop drücke sollte die unterbrochen werden. Nur bekomme ich die Stop Msg ja nie da er ja noch in der Schleife hängt.



  • Also eine Möglichkeit wäre es, das ganze über einen Timer zu machen und in WM_TIMER dann die entsprechenden Aktionen durchzuführen. Eine andere Möglichkeit wäre es noch, in der Schleife nochmal manuell immer des anstehenden Messages zu verarbeiten - oder du machst es gleich "richtig" und nimmst einen extra Thread 🙂



  • Wie mach ich die in einen extra thread?



  • _beginthread()



  • Frag doch einfach in der Schleife deine MessageLoop ab. Hier etwas Delphi Code:

    procedure ProcessMessages(hWnd: DWORD);
    var
      Msg: TMsg;
    begin
      while PeekMessage(Msg, hWnd, 0, 0, PM_REMOVE) do
        begin
          TranslateMessage(Msg);
          DispatchMessage(Msg);
        end;
    end;
    


  • Sry für die Frage aber hat da mal einer ein bsp?



  • zu was 😕



  • Hat sich erledigt. hab das jetzt so:

    threadHandle=CreateThread(NULL,200,&ChoseWS,NULL,0,&threadID);
    

    Und so:

    DWORD threadID;
    HANDLE threadHandle;
    
    DWORD WINAPI ChoseWS(LPVOID param1)
    {
    
       return 0;
    }
    

    Geht alles ganz Super. Nur leider weis ich nich wie ich den Threat Sschließen kann. Mit ExitThreat gins irgent wie net.



  • Nimm _beginthread anstatt CreateThread.



  • das ging bei mir irgent wie net.



  • Nimm trotzdem _beginthread der _beginthreadex. Wenn es die Funktion nicht gibt, sag uns welchen Compiler du benutzt.
    CreateThread sollte man nur dann direkt aufrufen, wenn man genau weiß, was man tut.

    Ein Thread sollte nicht durch einen Aufruf von ExitThread beendet werden. Lass den Thread einfach auslaufen; durch das return der Thread-Funktion wird er beendet.



  • Warum? Geht ja so super nur halt das abbrechen nicht.



  • Die Antwort davor war nur gekommen weil mein Browser rum gesponnen hat.

    Naja leider is mein Thread ein "Endlos" Threat. Daher kann ich ihn nicht auslaufen lassen.



  • Dann nimmst du einfach eine Variable, die du im Thread abfragst - ist sie gesetzt (von außen um den Thread zu beenden) lässt du den Thread auslaufen



  • Klausy schrieb:

    Warum? Geht ja so super nur halt das abbrechen nicht.

    cd9000 schrieb:

    CreateThread sollte man nur dann direkt aufrufen, wenn man genau weiß, was man tut.

    Weißt du wirklich genau, welche Fehler du dir damit einhandeln kannst?
    Durch den CreateThread-Aufruf wird die C-Lib für diesen Thread nicht initialisiert. Das bedeutet, dass manche Aufrufe der C-Lib plötzlich nicht mehr richtig arbeiten.
    Klassisches Beispiel dazu ist strtok.



  • Ich würder gern _beginthread benutzen nur komme ich damit nich klar.



  • Was ist denn damit dein Problem? 🙄



  • Naja ich habs bis jetzt halt noch nich hin bekommen ein Threat zu starten.





  • Das Porblems is jetzt. Ja das ich im Projekt Multithreating anschalten muss. Nur leider benutze ich kein VC++ um Winapi zu progen. Sonder andren Compiler der diese Option nich besitzt. Kann ich diese Option auch irgent wie Code geseuert anschalten?



  • Welchen Compiler nutzt du denn? Evtl. bist du dann aber im entsprechenden Forum (BCB bzw. Andere Compiler) besser augehoben bzw. stellst evtl. dort mal direkt die Frage, wie du Multithreading damit verwenden kannst 😉


Anmelden zum Antworten