Chinaunix首页 | 论坛 | 博客
  • 博客访问: 66702
  • 博文数量: 29
  • 博客积分: 1500
  • 博客等级: 上尉
  • 技术积分: 270
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-12 14:09
文章分类

全部博文(29)

文章存档

2017年(1)

2012年(1)

2011年(5)

2010年(2)

2009年(20)

我的朋友
最近访客

分类:

2009-11-13 11:14:07

 

单击右键弹出菜单

 

0397 单击右键弹出菜单

在应用程序中单击右键弹出菜单可以方便用户的操作,要实现右键弹出菜单需要调用CMenu类的TrackPopupMenu方法,该方法用于显示一个弹出式菜单。如图6.38所示。

程序代码如下:

void CPopupMenuDlg::OnRButtonUp(UINT nFlags, CPoint point)

{

    CMenu* pPopup = m_Menu.GetSubMenu(0);

    CRect rc;

    ClientToScreen(&point);

    rc.top = point.x;

    rc.left = point.y;

    pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_VERTICAL,

        rc.top,rc.left,this,&rc);

    CDialog::OnRButtonUp(nFlags, point);

}

单击右键弹出菜单 - Young - 任我遨游

图6.38 单击右键弹出菜单

0398 可以下拉的菜单

在使用Word等程序时,会发现一些不常用的菜单都被隐藏了,取而代之的是一个下箭头“︾”,单击这个菜单项后会显示出那些被隐藏的菜单。通过DeleteMenu方法和InsertMenu方法来动态删除和添加菜单,从而实现这个功能。如图6.39和图6.40所示。

单击右键弹出菜单 - Young - 任我遨游       单击右键弹出菜单 - Young - 任我遨游

                 图6.39 初始时显示菜单                         图6.40 下拉后的菜单

程序代码如下:

void CDownMenuDlg::OnMenudown()

{

    CMenu* m_pMenu;

    m_pMenu = m_Menu.GetSubMenu(0);

    m_pMenu->DeleteMenu(3,MF_BYPOSITION);

    m_pMenu->InsertMenu(3,MF_BYPOSITION,10001,"复制");

    m_pMenu->InsertMenu(4,MF_BYPOSITION,10002,"粘贴");

    m_pMenu->InsertMenu(5,MF_BYPOSITION,10003,"打印");

    SetMenu(&m_Menu);

}

0399 任务栏托盘弹出菜单

要设计任务栏托盘菜单,需要使用Shell_NotifyIcon函数和NOTIFYICONDATA结构来实现。如图6.41所示。

单击右键弹出菜单 - Young - 任我遨游

图6.41 任务栏托盘弹出菜单

程序代码如下:

BOOL CSysSalverDlg::OnInitDialog()

{

    …… //此处代码省略

    m_Menu.LoadMenu(IDR_MENU1);

    //添加系统托盘

    char lpszTip[]="明日科技";

    NOTIFYICONDATA data;

    data.cbSize=sizeof(NOTIFYICONDATA);

    data.hWnd=m_hWnd;

    lstrcpyn(data.szTip,lpszTip,sizeof(lpszTip));

    data.uCallbackMessage=WM_ONTRAY;

    data.uFlags=NIF_MESSAGE|NIF_ICON|NIF_TIP;

    data.hIcon=m_hIcon;

    data.uID=IDR_MAINFRAME;

    Shell_NotifyIcon(NIM_ADD,&data);

    return TRUE;

}

void CSysSalverDlg::OnTray(WPARAM wParam, LPARAM lParam)

{

    UINT uMouseMsg=(UINT) lParam;

    if(uMouseMsg==WM_RBUTTONDOWN)

    {

        CMenu* pPopup = m_Menu.GetSubMenu(0);

        CPoint point;

        GetCursorPos(&point);

        pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_VERTICAL,

               point.x,point.y,AfxGetApp()->m_pMainWnd,TPM_LEFTALIGN);        

    }

}

void CSysSalverDlg::OnMenuexit()

{

    if(MessageBox("确定要退出吗?","系统提示",MB_OKCANCEL|MB_ICONQUESTION)!=1)

        return;   

    CDialog::OnCancel();

}

void CSysSalverDlg::OnDestroy()

{

    CDialog::OnDestroy();

   

    NOTIFYICONDATA data;

    data.hWnd=m_hWnd;

    data.uID=IDR_MAINFRAME;

    Shell_NotifyIcon(NIM_DELETE,&data);

}

0400 绘制渐变效果的菜单

如今的许多应用软件都具有漂亮的菜单。在Visual C++中,如何设计这些菜单呢?本例中设计了一个渐变效果的菜单,效果如图6.42所示。

单击右键弹出菜单 - Young - 任我遨游

图6.42 绘制渐变效果的菜单

实现菜单的绘制,需要改写CMenu类的DrawItem方法和MeasureItem方法,在DrawItem方法中根据菜单项的当前状态绘制菜单,在MeasureItem方法中根据菜单项的文本设置菜单项的大小。程序主要代码如下:

//菜单类的声明

struct CMenuItemInfo

{

    CString m_ItemText; //菜单项文本

    int m_ItemID;        //菜单标记 -2顶层菜单,-1弹出式菜单,0分隔条,其他普通菜单

};

class CMyMenu : public CMenu

{

public:

    CMyMenu();

    virtual ~CMyMenu();

    CMenuItemInfo m_ItemLists[MAX_MENUCOUNT]; //菜单项信息

    int m_index;     //临时索引

    int m_iconindex; //菜单项图标索引

    BOOL ChangeMenuItem(CMenu* m_menu,BOOL m_Toped = FALSE);

    BOOL AttatchMenu(UINT m_uID);

    void DrawItemText(CDC* m_pdc,LPSTR str,CRect m_rect);

    void DrawTopMenu(CDC* m_pdc,CRect m_rect,BOOL m_selected = FALSE); //绘制顶层菜单

    void DrawSeparater(CDC* m_pdc,CRect m_rect);//绘制分隔条

    void DrawComMenu(CDC* m_pdc,CRect m_rect,COLORREF m_fromcolor,COLORREF m_tocolor, BOOL m_selected = FALSE);

   

    //override memu's virtual method

    virtual void MeasureItem( LPMEASUREITEMSTRUCT lpStruct ); //设置菜单项大小

    virtual void DrawItem( LPDRAWITEMSTRUCT lpStruct );       //重绘菜单项

};

//菜单类的实现

CMyMenu::CMyMenu()

{

    m_index= 0;

}

CMyMenu::~CMyMenu()

{

}

BOOL CMyMenu::AttatchMenu(UINT m_uID)

{

    this->LoadMenu(m_uID);

    return TRUE;

}

BOOL CMyMenu::ChangeMenuItem(CMenu* m_menu,BOOL m_Toped)

{

    if (m_menu != NULL)

    {

        int m_itemcount = m_menu->GetMenuItemCount();

       for (int i=0;i< P>

        {

    m_menu->GetMenuString(i,m_ItemLists[m_index].m_ItemText,MF_BYPOSITION);

                int m_itemID = m_menu->GetMenuItemID(i);

            if (m_itemID==-1 && m_Toped)

            {

                m_itemID = -2;//顶层菜单

            };

            m_ItemLists[m_index].m_ItemID = m_itemID;

            m_menu->ModifyMenu(i,MF_OWNERDRAW|MF_BYPOSITION |MF_STRING,m_ItemLists[m_index].m_ItemID,(LPSTR)&(m_ItemLists[m_index]));

           

            m_index+=1;

             CMenu* m_subMenu = m_menu->GetSubMenu(i);

            if (m_subMenu)

            {

                ChangeMenuItem(m_subMenu);

            }

        }

    }

    return TRUE    ;

}

void CMyMenu::MeasureItem( LPMEASUREITEMSTRUCT lpStruct )

{

    if (lpStruct->CtlType==ODT_MENU)

    {

        lpStruct->itemHeight = ITEMHEIGHT;

        lpStruct->itemWidth = ITEMWIDTH;

        CMenuItemInfo* m_iteminfo;

        m_iteminfo = (CMenuItemInfo*)lpStruct->itemData;

        lpStruct->itemWidth =

((CMenuItemInfo*)lpStruct->itemData)->m_ItemText.GetLength()*10;

        switch(m_iteminfo->m_ItemID)

        {

            case 0: //分隔条

                {

                    lpStruct->itemHeight = 1;

                    break;

                }   

        }

    }

}

void CMyMenu::DrawItem( LPDRAWITEMSTRUCT lpStruct )

{

    if (lpStruct->CtlType==ODT_MENU)

    {

        if(lpStruct->itemData == NULL)    return;

        unsigned int m_state = lpStruct->itemState;

        CDC* m_dc = CDC::FromHandle(lpStruct->hDC);

         CString str = ((CMenuItemInfo*)(lpStruct->itemData))->m_ItemText;

        LPSTR m_str = str.GetBuffer(str.GetLength());

        int m_itemID = ((CMenuItemInfo*)(lpStruct->itemData))->m_ItemID;

        CRect m_rect = lpStruct->rcItem;

        m_dc->SetBkMode(TRANSPARENT);

        switch(m_itemID)

        {

        case -2:

            {

     DrawTopMenu(m_dc,m_rect,(m_state&ODS_SELECTED)||(m_state&0x0040)); //0x0040 ==ODS_HOTLIGHT

                DrawItemText(m_dc,m_str,m_rect);

                break;

            }

        case -1:

            {   

                DrawItemText(m_dc,m_str,m_rect);

                break;

            }

        case 0:

            {

                DrawSeparater(m_dc,m_rect);

                break;

            }

         default:

            {       

                DrawComMenu(m_dc,m_rect,0xfaa0,0xf00ff,m_state&ODS_SELECTED);

                DrawItemText(m_dc,m_str,m_rect);

                break;

            }

        }

    }

}

void CMyMenu::DrawItemText(CDC* m_pdc,LPSTR str,CRect m_rect)

{

    m_rect.DeflateRect(20,0);

    m_pdc->DrawText(str,m_rect,DT_SINGLELINE|DT_VCENTER|DT_LEFT);

}

void CMyMenu::DrawTopMenu(CDC* m_pdc,CRect m_rect,BOOL m_selected )

{

    if (m_selected)

    {

        m_pdc->SelectStockObject(BLACK_PEN);

        m_pdc->Rectangle(&m_rect);

        m_rect.DeflateRect(1,1);

        m_pdc->FillSolidRect(m_rect,RGB(150, 185, 255));

    }

    else

    {

        CRect rect;

        AfxGetMainWnd()->GetClientRect(rect);

        rect.top = m_rect.top;

         rect.bottom = m_rect.bottom;

        rect.left= 350;

        rect.right +=4;

        m_pdc->FillSolidRect(&rect,RGB(192,192, 192));

        m_pdc->FillSolidRect(&m_rect,RGB(192,192, 192));

    }

}

void CMyMenu::DrawSeparater(CDC* m_pdc,CRect m_rect)

{

    if (m_pdc != NULL)

    {

        m_pdc->Draw3dRect(m_rect,RGB(255,0,0),RGB(0,0,255));

    }

}

void CMyMenu::DrawComMenu(CDC* m_pdc,CRect m_rect,COLORREF m_fromcolor,COLORREF m_tocolor, BOOL m_selected )

{

    if (m_selected)

    {

       

        m_pdc->Rectangle(m_rect);    

        m_rect.DeflateRect(1,1);

        int r1,g1,b1;

        //读取渐变起点的颜色值

        r1 = GetRValue(m_fromcolor);

        g1 = GetGValue(m_fromcolor);

        b1 = GetBValue(m_fromcolor);

        int r2,g2,b2;

        //读取渐变终点的颜色值

        r2 = GetRValue(m_tocolor);

        g2 = GetGValue(m_tocolor);

        b2 = GetBValue(m_tocolor);

        float r3,g3,b3;

       

        r3 = ((float)(r2-r1)) / (float)(m_rect.Height());

        g3 = (float)(g2-g1)/(float)(m_rect.Height());           

        b3 = (float)(b2-b1)/(float)(m_rect.Height());

       

        COLORREF r,g,b;

        CPen* m_oldpen ;

        for (int i = m_rect.top;i< P>

        {

            r = r1+(int)r3*(i-m_rect.top);

            g = g1+(int)g3*(i-m_rect.top);

            b = b1+ (int)b3*(i-m_rect.top);

           

            CPen m_pen (PS_SOLID,1,RGB(r,g,b));

            m_oldpen = m_pdc->SelectObject(&m_pen);

            m_pdc->MoveTo(m_rect.left,i);

            m_pdc->LineTo(m_rect.right,i);

        }

        m_pdc->SelectObject(m_oldpen);

    }

    else

    {

        m_pdc->FillSolidRect(m_rect,RGB(0x000000F9, 0x000000F8, 0x000000F7));

    }

}

单击右键弹出菜单 - Young - 任我遨游0401 将菜单项的字体设置为粗体

在设计应用程序时,有时需要修改菜单项的字体。在程序中可以使用SystemParametersInfo函数来设置菜单项的字体信息。该函数语法如下:

BOOL SystemParametersInfo(UINT uiAction, UINT uiParam,PVOID pvParam,UINT fWinIni );

参数说明如下。

l     uiAction:表示函数执行的动作,如果为SPI_SETNONCLIENTMETRICS,表示这种窗口非客户区域的信息。

l     uiParam:该参数的含义依赖于uiAction参数。

l     pvParam:表示设置的参数信息。

l     fWinIni:表示是否更新用户窗口。

程序主要代码如下:

    //获取

    NONCLIENTMETRICS info;

    info.cbSize =sizeof(NONCLIENTMETRICS);

    SystemParametersInfo(SPI_GETNONCLIENTMETRICS,sizeof(NONCLIENTMETRICS),&info,0);

    info.lfMenuFont.lfWeight = 700;

    SystemParametersInfo(SPI_SETNONCLIENTMETRICS,sizeof(NONCLIENTMETRICS),

&info,SPIF_SENDCHANGE);

阅读(2081) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~