2017-04-20 60 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); 
} 
相关问题