您的位置:首页 > 其它

菜单悬浮

2015-08-20 18:16 316 查看
头文件

#pragma once

#include "SivExtendCtrlLib.h"

// CTreeCtrlEx

typedef void (*DRAWCALLBACK)(CDC* pDC,void* pTree);

class CBitmapMenu : public CMenu

{
DECLARE_DYNAMIC(CBitmapMenu)

public:
CBitmapMenu();
virtual ~CBitmapMenu();

public:
virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/);
virtual void MeasureItem(LPMEASUREITEMSTRUCT /*lpMeasureItemStruct*/);

public:
void SetMenuWidth(int nWid);
void SetMenuHeight(int nHei);
void SetDrawCallBack(DRAWCALLBACK pFn);
void SetDrawBitmapHandle(CBitmap* pBitmap/*HBITMAP hBitmap*/);

private:
int m_nWid;
int m_nHei;
DRAWCALLBACK m_pfnDraw;
//HBITMAP m_hBitmap;
//CBitmap* m_pBitmap;

};

class SIV_EXTENDCTRL_API CTreeCtrlEx : public CTreeCtrl

{
DECLARE_DYNAMIC(CTreeCtrlEx)

public:
CTreeCtrlEx();
virtual ~CTreeCtrlEx();

protected:
DECLARE_MESSAGE_MAP()

public:
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
virtual void PreSubclassWindow();

int m_nDrawItem;

private:
CBitmapMenu m_menu;
HBRUSH m_menuBackCl;
LONG m_nImageW;
LONG m_nImageH;
CPoint m_pt;

static void DrawMenuImage(CDC *pDC,void* pTree);
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
};

源文件:

// TreeCtrlEx.cpp : implementation file

//

#include "stdafx.h"

#include "SivExtendCtrlLib.h"

#include "TreeCtrlEx.h"

// CTreeCtrlEx

IMPLEMENT_DYNAMIC(CBitmapMenu, CMenu)

CBitmapMenu::CBitmapMenu()

{
m_nWid=-1;
m_nHei=-1;
m_pfnDraw=NULL;

}

CBitmapMenu::~CBitmapMenu()

{
/*if(m_pBitmap!=NULL)
delete m_pBitmap;*/

}

void CBitmapMenu::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)

{
// TODO:  Add your code to draw the specified item
if(m_pfnDraw!=NULL)
{
CDC* pDC=CDC::FromHandle(lpDrawItemStruct->hDC);
MENUINFO menuinfo;
menuinfo.cbSize=sizeof(MENUINFO);
menuinfo.fMask=MIM_MENUDATA;
GetMenuInfo(&menuinfo);
m_pfnDraw(pDC,(void*)(menuinfo.dwMenuData));
}
/*CDC* pDC=CDC::FromHandle(lpDrawItemStruct->hDC);
Bitmap* bp=Bitmap::FromHBITMAP(m_pBitmap,NULL);
Graphics gh(pDC->m_hDC);
gh.DrawImage(bp,0,0,bp->GetWidth(),bp->GetHeight());
delete bp;*/

}

void CBitmapMenu::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)

{
// TODO:  Add your code to determine the size of specified item
if(m_nWid!=-1)
  lpMeasureItemStruct->itemWidth=m_nWid;
if(m_nHei!=-1)
  lpMeasureItemStruct->itemHeight=m_nHei;

}

void CBitmapMenu::SetMenuWidth(int nWid)

{
m_nWid=nWid;

}

void CBitmapMenu::SetMenuHeight(int nHei)

{
m_nHei=nHei;

}

void CBitmapMenu::SetDrawCallBack(DRAWCALLBACK pFn)

{
m_pfnDraw=pFn;

}

//void CBitmapMenu::SetDrawBitmapHandle(CBitmap* pBitmap)

//{

// if(m_pBitmap!=NULL)

//   delete m_pBitmap;

//    m_pBitmap=pBitmap;

//}

IMPLEMENT_DYNAMIC(CTreeCtrlEx, CTreeCtrl)

CTreeCtrlEx::CTreeCtrlEx()

{
m_nDrawItem=0;
m_menuBackCl=CreateSolidBrush(RGB(255,255,255));
m_nImageW=-1;
m_nImageH=-1;

}

CTreeCtrlEx::~CTreeCtrlEx()

{
if(m_menu.GetSafeHmenu())

       m_menu.DestroyMenu();

DeleteObject(m_menuBackCl);

}

BEGIN_MESSAGE_MAP(CTreeCtrlEx, CTreeCtrl)
ON_WM_MOUSEMOVE()

END_MESSAGE_MAP()

// CTreeCtrlEx message handlers

void CTreeCtrlEx::OnMouseMove(UINT nFlags, CPoint point)

{
// TODO: Add your message handler code here and/or call default
UINT uFlags;
HTREEITEM hItem = HitTest(point, &uFlags);
BOOL bHas=ItemHasChildren(hItem);
HTREEITEM hItemRoot=GetRootItem();
//BOOL bRoot=
/*if(m_menu.GetSafeHmenu())
{
SetFocus();
m_menu.DestroyMenu();
}*/

if ((hItem != NULL) && (TVHT_ONITEMICON & uFlags)&&!bHas && hItemRoot!=hItem)
{
CPoint pt=point;
ClientToScreen(&pt);

CImageList *pImg = GetImageList( TVSIL_NORMAL );
IMAGEINFO imageinfo;
int nItem,nSelItem;
GetItemImage(hItem,nItem,nSelItem);
pImg->GetImageInfo( nItem, &imageinfo );

LONG nImageW=imageinfo.rcImage.right-imageinfo.rcImage.left;
LONG nImageH=imageinfo.rcImage.bottom-imageinfo.rcImage.top;

m_nImageW=nImageW;

        m_nImageH=nImageH;

RECT r;

        GetItemRect(hItem, &r, TRUE);
m_pt.x=r.left-nImageW-4;
m_pt.y=r.top+2;
ClientToScreen(&m_pt);
if(!m_menu.GetSafeHmenu())
{
TRACE(L"menu create\n");
if (m_menu.CreatePopupMenu())
{
//
//CBitmap *bmp = CBitmap::FromHandle(imageinfo.hbmImage);
//m_menu.SetDrawBitmapHandle(imageinfo.hbmImage);
MENUINFO menuinfo;
menuinfo.cbSize = sizeof(MENUINFO); 
menuinfo.fMask =MIM_MENUDATA|MIM_BACKGROUND/*|MIM_STYLE*/; 
menuinfo.dwMenuData = reinterpret_cast<ULONG_PTR>(this); 
menuinfo.hbrBack=m_menuBackCl;
menuinfo.dwStyle=/*MNS_MODELESS*/MNS_AUTODISMISS;

m_menu.SetMenuInfo(&menuinfo);

m_nDrawItem=nItem;
m_menu.SetDrawCallBack(DrawMenuImage);

int nCX=::GetSystemMetrics(SM_CXMENUCHECK);
nImageW=nImageW*2-nCX;
nImageH=nImageH*2-5;

m_menu.SetMenuWidth(nImageW);
m_menu.SetMenuHeight(nImageH);
UINT nFlag = MF_OWNERDRAW|MFS_DISABLED;
m_menu.AppendMenu(nFlag,0,L"");
UINT index = m_menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, m_pt.x, m_pt.y,this);
if(m_menu.GetSafeHmenu())
  m_menu.DestroyMenu();
}
}

/*else
{
CPoint pt=point;
ClientToScreen(&pt);

CImageList *pImg = GetImageList( TVSIL_NORMAL );
IMAGEINFO imageinfo;
int nItem,nSelItem;
GetItemImage(hItem,nItem,nSelItem);
pImg->GetImageInfo( nItem, &imageinfo );

LONG nImageW=imageinfo.rcImage.right-imageinfo.rcImage.left;
LONG nImageH=imageinfo.rcImage.bottom-imageinfo.rcImage.top;
RECT r;
GetItemRect(hItem, &r, TRUE);
pt.x=r.left-nImageW-4;
pt.y=r.top+2;
ClientToScreen(&pt);

UINT index = m_menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, this);
}*/
}

/*HTREEITEM hitem = HitTest( point, &nFlags );
if( nFlags & TVHT_ONITEMLABEL  )
{
ScreenToClient(&point);
CPoint pt=point;
ClientToScreen(&pt);

}*/

CTreeCtrl::OnMouseMove(nFlags, point);

}

void CTreeCtrlEx::PreSubclassWindow()

{
// TODO: Add your specialized code here and/or call the base class

CTreeCtrl::PreSubclassWindow();

}

void CTreeCtrlEx::DrawMenuImage(CDC *pDC,void* pTree)

{
if(pTree==NULL)
  return ;

CImageList *pImg = ((CTreeCtrlEx*)pTree)->GetImageList( TVSIL_NORMAL);
IMAGEINFO imageinfo;
pImg->GetImageInfo( ((CTreeCtrlEx*)pTree)->m_nDrawItem, &imageinfo );

CImageList tmpList;
tmpList.Create(pImg);
tmpList.Copy(0,((CTreeCtrlEx*)pTree)->m_nDrawItem,ILCF_SWAP);
CDC dcMem; 
CBitmap destBitmap;
LONG nImageW=imageinfo.rcImage.right-imageinfo.rcImage.left;
LONG nImageH=imageinfo.rcImage.bottom-imageinfo.rcImage.top;

dcMem.CreateCompatibleDC (pDC); 
destBitmap.CreateCompatibleBitmap (pDC, nImageW, nImageH);
CBitmap* pBmpOld =dcMem.SelectObject(&destBitmap);
BOOL b=tmpList.Draw(&dcMem, 0,CPoint (0,0),ILD_NORMAL);//DrawIndirect (&dcMem, 0, CPoint (0, 0),CSize (nImageW, nImageH), CPoint (0, 0));

int nCX=::GetSystemMetrics(SM_CXMENUCHECK);
int nImageWNew=nImageW*2-nCX;
int nImageHNew=nImageH*2-5;

pDC->SetStretchBltMode(HALFTONE) ;
pDC->StretchBlt(0,0,/*nImageWNew*/nImageW*2-3,nImageHNew,&dcMem,0,0,nImageW,nImageH,SRCCOPY);
//pDC->BitBlt(0,0,nImageW,nImageH,&dcMem,0,0,SRCCOPY);

dcMem.SelectObject(pBmpOld);
destBitmap.DeleteObject();
dcMem.DeleteDC();
/*Bitmap* bp=Bitmap::FromHBITMAP(imageinfo.hbmImage,NULL);
Graphics gh(pDC->m_hDC);
gh.DrawImage(bp,0,0,bp->GetWidth(),bp->GetHeight());
delete bp;*/

}

LRESULT CTreeCtrlEx::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)

{
// TODO: Add your specialized code here and/or call the base class
if(message==WM_ENTERIDLE)
{
CPoint pt,pt1;
GetCursorPos(&pt);
ScreenToClient(&pt);

pt1=m_pt;
ScreenToClient(&pt1);
CRect rc;
rc.left=pt1.x;
rc.top=pt1.y;
rc.right=rc.left+m_nImageW*2+3;
rc.bottom=rc.top+m_nImageH*2;

if(!rc.PtInRect(pt))
{
if(m_menu.GetSafeHmenu())
{
SendMessage(WM_CANCELMODE);
m_menu.DestroyMenu();
}
}
}

return CTreeCtrl::WindowProc(message, wParam, lParam);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: