现在钩子已经装好了.也可以在菜单上画字.现在的问题是每一个菜单项
的RECT和它的标题如何获取呢.请各位大大指教哈..

解决方案 »

  1.   

    这是设置钩子的部分。if (nCode == HC_ACTION) {
    if (pMsg->message == WM_CREATE) {
    pre_wndproc_hwnd *pValue = NULL;
    // Check is the class is already hook
    if (!m_mapWndProHwnd.Lookup(pMsg->hwnd, pValue)) {
    TCHAR szClassName[MAX_PATH] = _T("\0");
    ::GetClassName(pMsg->hwnd, szClassName, MAX_PATH);
    TRACE(_T("%s\n"), szClassName); if (!_tcscmp(_T("#32768"), szClassName)) {
    pre_wndproc_hwnd *pPre = new pre_wndproc_hwnd;
    memset(pPre, 0, sizeof(pre_wndproc_hwnd));
    pPre->hwnd = pMsg->hwnd;
    pPre->proc = reinterpret_cast<WNDPROC>(::GetWindowLong(pMsg->hwnd,
    GWL_WNDPROC)); m_arPreWndPro.push_back(pPre);
    m_mapWndProHwnd.SetAt(pPre->hwnd, pPre); DefWindowProc(pMsg->hwnd, WM_CREATE, wParam, lParam);
    SetWindowLong(pMsg->hwnd, GWL_WNDPROC, 
    reinterpret_cast<long>(MenuProc));
    }


    //m_arPreWndPro.push_back(pPre);
    // m_mapWndProHwnd.SetAt(pPre->hwnd, pPre);

    }


    }
    }
    这是画菜单的过程LRESULT CALLBACK Class::MenuProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
    pre_wndproc_hwnd  *oldproc =  NULL;
    m_mapWndProHwnd.Lookup(hwnd, oldproc); switch (uMsg) {
    case WM_CREATE : {
    TRACE(_T("Create menu now\n"));
    // Call default proc
    pre_wndproc_hwnd *pValue = NULL;
    m_mapWndProHwnd.Lookup(hwnd, pValue);
    ASSERT(pValue);
    pValue->proc(hwnd, uMsg, wParam, lParam);
    }
    break;
    case WM_PAINT:
    TRACE(_T("Need Paint Menu\n"));
    return tzg_paint::paint_menu(hwnd, wParam, lParam);

    case WM_DRAWITEM:
    TRACE(_T("Framework call Drawitem \n"));
    break;
    default:
    break;
    } //TRACE(_T("get a menu Message %#x\n"), uMsg);
    return ::CallWindowProc(oldproc->proc, hwnd, uMsg, wParam, lParam);
    }可是在下面的部分中得不到需要的。可能方法不对。请指教namespace tzg_paint {
    int _cdecl paint_menu(HWND hWnd, WPARAM wParam, LPARAM)
    {
    CRect rt;
    CWnd *pWnd = CWnd::FromHandle(hWnd);
    ASSERT(pWnd);
    CWindowDC dc(pWnd);

    GetWindowRect(hWnd, &rt);

    // translate to client
    LPPOINT pt = (PPOINT)&rt;
    ::ScreenToClient(hWnd, pt);
    ::ScreenToClient(hWnd, pt); VERIFY(dc.DrawEdge(&rt, BDR_RAISEDINNER, BF_RECT));

    //dc.DrawFrameControl(&rt,)
    TCHAR szMenuTitle[MAX_PATH] = _T("\0");

    INT nCount = ::GetMenuItemCount((HMENU)hWnd); // 这里得到的是-1 啊 GetMenuString((HMENU)hWnd, 0, szMenuTitle, MAX_PATH, MF_BYPOSITION);
    TRACE(_T("%s\n"), szMenuTitle); //输出为空
    return 0L;
    }
    };
      

  2.   

    This method copies the label of the specified menu item to the specified buffer. int GetMenuString(
    UINT nIDItem,
    LPTSTR lpString,
    int nMaxCount,
    UINT nFlags )
    const;int GetMenuString(
    UINT nIDItem,
    CString& rString,
    UINT nFlags )
    const; 
      

  3.   

    HMENU是在那里定义的?怎么没看到?
      

  4.   

    hmenu?为什么要HMENU.我SPY一下看到的是HWND.也就是菜单的句柄typedef /* [wire_marshal] */ void __RPC_FAR *HMENU; in wtypes.h line913
      

  5.   

    nCount = ::GetMenuItemCount((HMENU);  你问我啊,你的程序是这样用的。
      

  6.   

    INT nCount = ::GetMenuItemCount((HMENU)hWnd); // 这里得到的是-1 啊
    呵呵。CSDN把这一句回行了,其实你看到的是
    INT nCount = ::GetMenuItemCount((HMENU)
    hWnd); // 这里得到的是-1 啊
      

  7.   

    你的hWnd是否有效?if(hWnd==NULL)...
      

  8.   

    hWnd是有效滴··。不过不知道为什么。我用Spy看了一下的。Hwnd是跟Spy上的一样的
    可是ASSERT(::IsMenu((HMENU)hWnd));却触发了