2014-01-09 65 views
1

我有一個工具欄到我的應用程序中的一個窗口。我已閱讀 MSDN docs並可處理命令和通知消息。我的問題是附加到工具欄上的按鈕的下拉菜單。菜單項打開模式對話框並等待用戶完成設置更改。然而,當用戶點擊'ok'或'cancel'焦點返回到主窗口時,工具欄仍然處於鼠標左鍵關閉的狀態,所以每次將鼠標拖動到單擊按鈕所需的工具欄按鈕上'按鈕被檢查'狀態,'出現'被按下。Win32工具欄下拉按鈕消息處理

問題是跟蹤鼠標事件嗎?

這裏是通知消息的窗口過程中操作:

case WM_NOTIFY: 
     { 
      LPNMHDR lpnm = ((LPNMHDR)lParam); 
      LPNMTOOLBAR lpnmTB = ((LPNMTOOLBAR)lParam); 

      switch(lpnm->code) 
      { 
      case TBN_DROPDOWN: 
       { 
        // Get the coordinates of the button. 
        RECT rc; 
        SendMessage(lpnmTB->hdr.hwndFrom, TB_GETRECT, (WPARAM)lpnmTB->iItem, (LPARAM)&rc); 

        // Convert to screen coordinates.    
        MapWindowPoints(lpnmTB->hdr.hwndFrom, HWND_DESKTOP, (LPPOINT)&rc, 2);       

        // handle dropdown menus 
        return HandleTexEditDropdown(hWnd, lpnmTB, rc); 
       } 
      default: 
       break; 
      } 
      break; 
     } 

這裏是處理TexEditDropdown():

LRESULT CALLBACK CWindowManager::HandleTexEditDropdown(HWND hWnd, LPNMTOOLBAR lpnm, RECT &rc) 
{ 
    HRESULT hr = S_OK; 

    switch(lpnm->iItem) 
    { 
    case IDM_EDITTEXTURE_FILL: 
     { 
      // Get the menu. 
      HMENU hMenuLoaded = LoadMenu(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_BUCKETFILL)); 

      // Get the submenu for the first menu item. 
      HMENU hPopupMenu = GetSubMenu(hMenuLoaded, 0); 

      // Set up the pop-up menu. 
      // In case the toolbar is too close to the bottom of the screen, 
      // set rcExclude equal to the button rectangle and the menu will appear above 
      // the button, and not below it. 
      TPMPARAMS tpm; 

      tpm.cbSize = sizeof(TPMPARAMS); 
      tpm.rcExclude = rc; 

      // Show the menu and wait for input. 
      // If the user selects an item, its WM_COMMAND is sent. 

      INT nCmd = TrackPopupMenuEx(hPopupMenu, 
       TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_VERTICAL | TPM_RETURNCMD, 
       rc.left, rc.bottom, hWnd, &tpm); 

      DestroyMenu(hMenuLoaded); 
      switch(nCmd) 
      { 
      case IDM_BUCKETFILLSETTINGS: 
       DialogBox(GetModuleHandle(NULL), 
        MAKEINTRESOURCE(IDD_TEXEDITBUCKETFILL), 
        hWnd, 
        (DLGPROC)TexEditSettingsProc); 
       break; 
      default: 
       return 0; 
      } 

      SendMessage((HWND)lpnm->hdr.hwndFrom, TB_MARKBUTTON, lpnm->iItem, MAKELPARAM(FALSE, 0)); 
      UpdateWindow(hWnd); 
      SetStateChange(); 
      return 1; 
     } 
    case IDM_EDITTEXTURE_RECOVER: 
     { 
      // Get the menu. 
      HMENU hMenuLoaded = LoadMenu(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_RECOVER)); 

      // Get the submenu for the first menu item. 
      HMENU hPopupMenu = GetSubMenu(hMenuLoaded, 0); 

      // Set up the pop-up menu. 
      // In case the toolbar is too close to the bottom of the screen, 
      // set rcExclude equal to the button rectangle and the menu will appear above 
      // the button, and not below it. 
      TPMPARAMS tpm; 

      tpm.cbSize = sizeof(TPMPARAMS); 
      tpm.rcExclude = rc; 

      // Show the menu and wait for input. 
      // If the user selects an item, its WM_COMMAND is sent. 

      INT nCmd = TrackPopupMenuEx(hPopupMenu, 
       TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_VERTICAL | TPM_RETURNCMD, 
       rc.left, rc.bottom, hWnd, &tpm); 

      DestroyMenu(hMenuLoaded); 

      switch(nCmd) 
      { 
      case IDM_RECOVERFILE: 
       { 
        WCHAR wcs[ MAX_PATH ] = L"", 
         wcsFiletype[ MAX_PATH ] = L"", 
         wcsFilename[ MAX_PATH ] = L""; 
        D3DXIMAGE_INFO info; 

        // get currently loaded image info 
        if(FAILED(hr = CTextureEditor::GetImageInfo(&info))) 
        { 
         DebugStringDX(ClassName, "Failed to CTextureEditor::GetImageInfo() at AuxiliaryViewportProcess()", __LINE__, hr); 
         break; 
        } 

        if(!CTextureEditor::CatImageFileType(info.ImageFileFormat, wcsFiletype)) 
        { 
         DebugStringDX(ClassName, "Invalid image filetype at AuxiliaryViewportProcess()", __LINE__, hr); 
         break; 
        } 

        wsprintf(wcs, L"GDEImage Filetype (*%s)", wcsFiletype); 
        memcpy(&wcs[ 26 ], L"*", sizeof(WCHAR)); 
        memcpy(&wcs[ 27 ], wcsFiletype, 4 * sizeof(WCHAR)); 

        // Declare and initialize an OPENFILENAME struct to use for OpenFile Dialog 
        OPENFILENAME ofn; 
        ZeroMemory((void*)&ofn, sizeof(OPENFILENAME)); 

        ofn.lStructSize = sizeof(ofn); // SEE NOTE BELOW 
        ofn.hwndOwner = hWnd; 
        ofn.lpstrTitle = L"Recover Image From File"; 
        ofn.lpstrFilter = wcs; 
        ofn.lpstrFile = wcsFilename; 
        ofn.nMaxFile = MAX_PATH; 
        ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; 
        ofn.lpstrDefExt = L"image file"; 
        ofn.lpstrInitialDir = app.GetBinDirectory(); 

        // OpenFile Dialog 
        if(GetOpenFileName(&ofn)) 
        {          
         if(FAILED(hr = CTextureEditor::Recover(0, wcsFilename))) 
         { 
          DebugStringDX(ClassName, "Failed to CTextureEditor::Recover() at AuxiliaryViewportProc()", __LINE__, hr); 
          break; 
         } 
        } 
        break; 
       } 
      default: 
       return 0; 
      } 

      SendMessage((HWND)lpnm->hdr.hwndFrom, TB_MARKBUTTON, lpnm->iItem, MAKELPARAM(FALSE, 0)); 
      UpdateWindow(hWnd); 
      SetStateChange(); 
      return 1; 
     } 
    default: 
     return 0; 
    } 
    return 0; 
} 

回答

2

我認爲TBN_DROPDOWN返回值是不正確的 - 你是返回1其中映射到TBDDRET_NODEFAULT表示「下拉未處理」,則需要返回TBDDRET_DEFAULTTBDDRET_TREATPRESSED

+0

修復它。謝謝 –