2017-04-20 1 views
0

Im Fenster API habe ich ein Popup-Menü, das 3 Elemente "Line", "Circle" und "Exit" enthält.Gewusst wie: ausgewählter Menüpunkt in Win32 API

Mein Programm ist es, den Benutzer eine Form zum Zeichnen wählen lassen, dann nimmt die Punkte, Parameter (d. H. Start- und Endpunkte der Linie, ...). Dies ist Teil des Codes, den ich bisher geschrieben habe.

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, 
    WPARAM wParam, LPARAM lParam) { 

    HMENU hMenu; 
    POINT point; 
    HDC hdc; 
    hdc = GetDC(hwnd); 
    static int x1, y1,x2,y2,count = 0; 
    switch (msg) { 

    case WM_LBUTTONDOWN: 
     count++; 
     if (count == 1) 
     { 
      x1 = LOWORD(lParam); 
      y1 = HIWORD(lParam); 
     } 
     else 
     { 
      x2 = LOWORD(lParam); 
      y2 = HIWORD(lParam); 

      // I think the problem goes here, it never execute else part 
      //even if global_ID ==2, Am I missing something? 

      if (global_ID == 1)//Line 
      {DirectMethod(hdc, x1, y1, x2, y2, RGB(0, 0, 0));} 
      else if (global_ID == 2)//Circle 
      {Ellipse(hdc, x1, y1, x2, y2);} 
      count = 0; 
     } 
    case WM_COMMAND: 

     switch (LOWORD(wParam)) { 
     case IDM_FILE_LINE: 
      global_ID = 1; 
      break; 
     case IDM_FILE_CIRCLE: 
      global_ID = 2;//Global Variable 
      break; 

     case IDM_FILE_QUIT: 

      SendMessage(hwnd, WM_CLOSE, 0, 0); 
      break; 
     } 

     break; 

    case WM_RBUTTONUP: 

     point.x = LOWORD(lParam); 
     point.y = HIWORD(lParam); 

     hMenu = CreatePopupMenu(); 
     ClientToScreen(hwnd, &point); 

     AppendMenuW(hMenu, MF_STRING, IDM_FILE_LINE, L"&line"); 
     AppendMenuW(hMenu, MF_STRING, IDM_FILE_CIRCLE, L"&Circle"); 
     AppendMenuW(hMenu, MF_SEPARATOR, 0, NULL); 
     AppendMenuW(hMenu, MF_STRING, IDM_FILE_QUIT, L"&Quit"); 

     TrackPopupMenu(hMenu, TPM_RIGHTBUTTON, point.x, point.y, 0, hwnd, NULL); 
     DestroyMenu(hMenu); 
     break; 

    case WM_DESTROY: 

     PostQuitMessage(0); 
     break; 
    } 

    return DefWindowProcW(hwnd, msg, wParam, lParam); 
} 

Was ich tun möchte, ist, basierend auf ausgewählten Menüpunkt (Linie, Kreis, ...) Ich habe keine bestimmtes Stück Code ausführen, die auch Klicks auf immer Maus von Benutzer abhängt (WM_LBUTTONDOWN).

Zum Beispiel: Wenn der Benutzer "Linie" auswählte, sollte ich zwei Punkte nehmen, um diese Linie zu zeichnen.

+0

Was ist Ihre eigentliche Frage? Ihr Code erkennt bereits, welcher Menüeintrag ausgewählt ist, der von der Meldung "WM_COMMAND" gemeldet wird. Also, Ihr Problem ist nur die Benutzereingaben sammeln? Zum Beispiel könnte Ihr 'WM_COMMAND'-Handler ein Flag setzen, das die Anzahl der benötigten Koordinaten angibt, und dann Ihren Handler' WM_LBUTTONDOWN/UP' speichern lassen, bis diese Zahl erreicht ist. Was ist das eigentliche Problem, das Sie haben? –

+0

@RemyLebeau Das Problem ist, wenn ein Menüelement ausgewählt ist Ich ändere "global_ID" -Wert, um zu wissen, welcher Menüpunkt ausgewählt ist, aber innerhalb "WM_LBUTTONDOWN" es "immer" die if-Anweisung ausführen und nie sonst Teil ausführt, und ich habe debugged Dieser Code und "global_ID" wird auf "2" gesetzt. Was ich meine, es soll "anderen" Teil ausführen, aber es immer ausführen "wenn" Teil –

+0

Sie sollten diese Details in Ihrer Frage angegeben haben. Was Sie beschreiben, sollte nicht möglich sein, da 'global_ID' nicht lokal für' WndProc() 'ist, also würde jeder Wert, den' WM_COMMAND' zuweist, durch den nachfolgenden 'WM_LBUTTONDOWN' übertragen werden. Allerdings gibt es logische Lücken in Ihrem Code: 1) Sie zählen Mausklicks, auch wenn Sie nicht sein sollten. Wenn Sie 'global_ID' setzen, setzen Sie' count' nicht auf 0 zurück; 2) 'WM_LBUTTONDOWN' sollte überhaupt nichts tun, wenn' global_ID' nicht 1 oder 2 ist; 3) Sie '' Globales_ID 'nach dem Aufruf von' DirectMethod() '/' Ellipse() '... –

Antwort

0

Es gibt Logiklöcher in Ihrem Code:

  1. Sie zählen Maus selbst klickt, wenn Sie nicht sein sollte. Wenn Ihr WM_COMMAND-Handler global_ID setzt, setzen Sie auch count nicht auf 0 zurück, so dass ein nachfolgender Klick möglicherweise die Zuweisung x1/y1 überspringt, da count möglicherweise bereits > 0 ist.

  2. Ihre WM_LBUTTONDOWN Handler sollte nicht überhaupt etwas zu tun, wenn global_ID nicht 1 oder 2 ist

  3. Sie nicht global_ID sind Neueinstellung nach DirectMethod()/Ellipse() Aufruf, so WM_LBUTTONDOWN wird nur das Zählen halten Klicks endlos und seine Durchführung Zeichnungen bei jedem weiteren Klick.

  4. Ihre WM_LBUTTONDOWN ist eine erforderliche break Anweisung fehlt, so wird jede WM_LBUTTONDOWN Nachricht an den WM_COMMAND Code fallen durch.

Versuchen Sie stattdessen:

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 
{ 
    static int x1, y1, x2, y2, count = 0, global_ID = 0; 

    switch (msg) 
    { 
     case WM_LBUTTONDOWN: 
     { 
      switch (global_ID) 
      { 
       case 1: //Line 
       case 2: //Circle 
       { 
        ++count; 
        if (count == 1) 
        { 
         x1 = GET_X_LPARAM(lParam); 
         y1 = GET_Y_LPARAM(lParam); 
        } 
        else 
        { 
         x2 = GET_X_LPARAM(lParam); 
         y2 = GET_Y_LPARAM(lParam); 

         HDC hdc = GetDC(hwnd); 

         if (global_ID == 1) { 
          DirectMethod(hdc, x1, y1, x2, y2, RGB(0, 0, 0)); 
         } 
         else { 
          Ellipse(hdc, x1, y1, x2, y2); 
         } 

         ReleaseDC(hwnd, hdc); 

         global_ID = 0; 
        } 

        break; 
       } 
      } 

      break; 
     } 

     case WM_COMMAND: 
     { 
      switch (LOWORD(wParam)) 
      { 
       case IDM_FILE_LINE: 
        global_ID = 1; 
        count = 0; 
        break; 

       case IDM_FILE_CIRCLE: 
        global_ID = 2; 
        count = 0; 
        break; 

       case IDM_FILE_QUIT: 
        SendMessage(hwnd, WM_CLOSE, 0, 0); 
        break; 
      } 

      break; 
     } 

     case WM_RBUTTONUP: 
     { 
      POINT point; 
      point.x = GET_X_LPARAM(lParam); 
      point.y = GET_Y_LPARAM(lParam); 
      ClientToScreen(hwnd, &point); 

      HMENU hMenu = CreatePopupMenu();   
      AppendMenuW(hMenu, MF_STRING, IDM_FILE_LINE, L"&line"); 
      AppendMenuW(hMenu, MF_STRING, IDM_FILE_CIRCLE, L"&Circle"); 
      AppendMenuW(hMenu, MF_SEPARATOR, 0, NULL); 
      AppendMenuW(hMenu, MF_STRING, IDM_FILE_QUIT, L"&Quit"); 
      TrackPopupMenu(hMenu, TPM_RIGHTBUTTON, point.x, point.y, 0, hwnd, NULL); 
      DestroyMenu(hMenu); 

      break; 
     } 

     case WM_DESTROY: 
     { 
      PostQuitMessage(0); 
      break; 
     } 
    } 

    return DefWindowProcW(hwnd, msg, wParam, lParam); 
} 
Verwandte Themen