2017-04-20 70 views
0

在窗口API中,我有一個彈出菜單,其中分別包含3行「Line」,「Circle」和「Exit」。如何知道Win32 API中的選定菜單項目

我的程序是讓用戶選擇要繪製的形狀,然後獲取點,參數(即線的起點和終點...)。這是我迄今爲止編寫的代碼的一部分。

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); 
} 

我想什麼做的是,根據選擇的菜單項(直線,圓,......)我執行特定的一塊也依賴於從用戶(WM_LBUTTONDOWN)獲得鼠標點擊代碼。

例如: 如果用戶選擇「線」,我應該採取兩點來繪製該線。

+0

你是什麼實際問題?您的代碼已經在檢測哪個菜單項被選中,這是由WM_COMMAND消息報告的。那麼,你的問題只是收集用戶的輸入?例如,你可以讓你的'WM_COMMAND'處理程序設置一個標誌,指示所需座標的數量,然後讓你的'WM_LBUTTONDOWN/UP'處理程序保存座標直到達到該數字。你遇到的實際問題是什麼? –

+0

@RemyLebeau問題是當選擇一個菜單項我改變「global_ID」的值,以知道哪個菜單項被選中,但在「WM_LBUTTONDOWN」它「總是」執行if語句,永遠不會執行其他部分,我已調試該代碼和「global_ID」設置爲「2」。我的意思是假設執行「其他」部分,但總是執行「如果」部分 –

+0

你應該在你的問題中說明這些細節。你所描述的不應該是可能的,因爲'global_ID'不是'WndProc()'本地的,所以'WM_COMMAND'指定的任何值都會被傳遞給後續的'WM_LBUTTONDOWN'。但是,代碼中存在邏輯漏洞:1)即使不應該出現鼠標點擊,也要計數。當你設置'global_ID'時,你不會將'count'重置爲0; 2)'global_ID'不是1或2時,'WM_LBUTTONDOWN'不應該做任何事情; 3)在調用'DirectMethod()'/'Ellipse()'... –

回答

0

有在你的代碼的邏輯漏洞:

  1. 你指望鼠標點擊,即使你不應該。當您的WM_COMMAND處理程序設置爲global_ID時,您並未將count重置爲0,因此隨後的點擊最終可能會跳過x1/y1的分配,因爲count可能已經是。

  2. 1或2

  3. 你是不是重置global_ID調用DirectMethod()/Ellipse()

  4. WM_LBUTTONDOWN處理程序不應該在所有做任何事情的時候global_ID是沒有,所以WM_LBUTTONDOWN只會繼續點擊計數不休,並執行其每隔一次點擊圖紙。

  5. WM_LBUTTONDOWN缺少必要break聲明,所以每一個WM_LBUTTONDOWN消息將始終陷入WM_COMMAND代碼。

試試這個:

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); 
} 
相關問題