菜单悬浮
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);
}
#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);
}
相关文章推荐
- 无题
- php中$this->是什么意思
- Struts学习笔记——01
- CoreAnimation(CA)
- MR案例:Reduce-Join
- Android性能优化典范 - 第3季
- 表格显示问题
- NYOJ 364 田忌赛马(贪心)
- 【php】如何提高网页加载速度?
- eclipse导入项目,项目名出现红叉的情况
- android 网络请求图片,返回值为空的解决办法
- 机房收费系统个人重构版:暮然回首,灯火阑珊
- recommender systems
- 监听ContentProvider的数据变化
- shell 带参数脚本
- 头文件与源文件
- ubuntu 查看版本
- Android性能优化典范
- ViewPage和Fragment上 实现BadgeView消息提醒(仿旧微信)
- VBScript中处理浮点数相减的精度问题