用于EagleEye3.0 规则集漏报和误报测试的示例项目,项目收集于github和gitee
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

281 lines
8.0 KiB

#pragma once
#include <core/sobjType.h>
#include <sobject/Sobject.hpp>
#include "core/SNativeWnd.h"
#include "res.mgr/Sskinpool.h"
namespace SOUI
{
#define CX_ICON 16 //支持的图标的宽度
#define CY_ICON 16 //支持的图标的高度
class SMenuAttr:public SObject, public TObjRefImpl<IObjRef>
{
friend class SMenu;
friend class SMenuODWnd;
SOUI_CLASS_NAME(SMenuAttr, L"menuattr")
public:
SMenuAttr();
~SMenuAttr();
void SetScale(int scale);
SOUI_ATTRS_BEGIN()
ATTR_SKIN(L"itemSkin",m_pItemSkin,FALSE)
ATTR_SKIN(L"iconSkin",m_pIconSkin,FALSE)
ATTR_SKIN(L"sepSkin",m_pSepSkin,FALSE)
ATTR_SKIN(L"checkSkin",m_pCheckSkin,FALSE)
ATTR_LAYOUTSIZE(L"itemHeight",m_nItemHei,FALSE)
ATTR_LAYOUTSIZE(L"iconMargin",m_nIconMargin,FALSE)
ATTR_LAYOUTSIZE(L"textMargin",m_nTextMargin,FALSE)
ATTR_LAYOUTSIZE(L"maxWidth",m_nMaxWidth,FALSE)
ATTR_LAYOUTSIZE2(L"iconSize",m_szIcon,FALSE)
ATTR_FONT(L"font",m_dpiFont,FALSE)
ATTR_COLOR(L"colorText",m_crTxtNormal,FALSE)
ATTR_COLOR(L"colorTextSel",m_crTxtSel,FALSE)
ATTR_COLOR(L"cororTextGray",m_crTxtGray,FALSE)
ATTR_STRINGW(L"trCtx",m_strTrCtx,FALSE)
SOUI_ATTRS_END()
protected:
int GetTextMargin();
int GetIconMargin();
CSize GetIconSize();
int GetItemHeight();
int GetMaxWidth();
int GetScale() const{return m_scale;}
SAutoRefPtr<IFont> GetFontPtr();
protected:
virtual void OnInitFinished(pugi::xml_node xmlNode);
SAutoRefPtr<ISkinObj> m_pItemSkin; //菜单项皮肤,包含2种状态:正常状态+选中状态
SAutoRefPtr<ISkinObj> m_pIconSkin; //菜单图标
SAutoRefPtr<ISkinObj> m_pSepSkin; //分割栏皮肤
SAutoRefPtr<ISkinObj> m_pCheckSkin; //选中状态,包含两种状态:勾选+圈选
SLayoutSize m_nItemHei; //菜单项高度
SLayoutSize m_nIconMargin;//图标边缘空间
SLayoutSize m_nTextMargin;//文本边缘空间
COLORREF m_crTxtNormal;//正常文本颜色
COLORREF m_crTxtSel; //选中文本颜色
COLORREF m_crTxtGray; //灰文本颜色
SLayoutSize m_szIcon[2]; //图标尺寸
SDpiAwareFont m_dpiFont;
SStringW m_strTrCtx; //翻译上下文
SLayoutSize m_nMaxWidth; //菜单项最大宽度
int m_scale;
};
struct SMenuItemData
{
SMenuItemData();
~SMenuItemData();
int iIcon;
SStringT strText;
UINT vHotKey;
ULONG_PTR dwUserData;
HICON hIcon;
};
template <class T>
class SOwnerDraw
{
public:
// Message map and handlers
BEGIN_MSG_MAP_EX(SOwnerDraw< T >)
MESSAGE_HANDLER(WM_DRAWITEM, OnDrawItem)
MESSAGE_HANDLER(WM_MEASUREITEM, OnMeasureItem)
MESSAGE_HANDLER(WM_COMPAREITEM, OnCompareItem)
MESSAGE_HANDLER(WM_DELETEITEM, OnDeleteItem)
MESSAGE_HANDLER(WM_MENUCHAR,OnMenuChar)
ALT_MSG_MAP(1)
MESSAGE_HANDLER(OCM_DRAWITEM, OnDrawItem)
MESSAGE_HANDLER(OCM_MEASUREITEM, OnMeasureItem)
MESSAGE_HANDLER(OCM_COMPAREITEM, OnCompareItem)
MESSAGE_HANDLER(OCM_DELETEITEM, OnDeleteItem)
END_MSG_MAP()
LRESULT OnDrawItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
{
T* pT = static_cast<T*>(this);
pT->SetMsgHandled(TRUE);
pT->DrawItem((LPDRAWITEMSTRUCT)lParam);
bHandled = pT->IsMsgHandled();
return (LRESULT)TRUE;
}
LRESULT OnMeasureItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
{
T* pT = static_cast<T*>(this);
pT->SetMsgHandled(TRUE);
pT->MeasureItem((LPMEASUREITEMSTRUCT)lParam);
bHandled = pT->IsMsgHandled();
return (LRESULT)TRUE;
}
LRESULT OnCompareItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
{
T* pT = static_cast<T*>(this);
pT->SetMsgHandled(TRUE);
bHandled = pT->IsMsgHandled();
return (LRESULT)pT->CompareItem((LPCOMPAREITEMSTRUCT)lParam);
}
LRESULT OnDeleteItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
{
T* pT = static_cast<T*>(this);
pT->SetMsgHandled(TRUE);
pT->DeleteItem((LPDELETEITEMSTRUCT)lParam);
bHandled = pT->IsMsgHandled();
return (LRESULT)TRUE;
}
LRESULT OnMenuChar(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
T* pT = static_cast<T*>(this);
pT->SetMsgHandled(TRUE);
UINT nChar = LOWORD(wParam);
UINT nFlags = HIWORD(wParam);
HMENU hMenu =(HMENU)lParam;
LRESULT lRes = pT->OnMenuChar(nChar,nFlags,hMenu);
bHandled = pT->IsMsgHandled();
return lRes;
}
// Overrideables
void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/)
{
// must be implemented
SASSERT(FALSE);
}
void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
if(lpMeasureItemStruct->CtlType != ODT_MENU)
{
// return default height for a system font
T* pT = static_cast<T*>(this);
HWND hWnd = pT->GetDlgItem(lpMeasureItemStruct->CtlID);
HDC dc = GetDC(hWnd);
TEXTMETRIC tm = { 0 };
GetTextMetrics(dc,&tm);
lpMeasureItemStruct->itemHeight = tm.tmHeight;
ReleaseDC(hWnd, dc);
}
else
lpMeasureItemStruct->itemHeight = ::GetSystemMetrics(SM_CYMENU);
}
int CompareItem(LPCOMPAREITEMSTRUCT /*lpCompareItemStruct*/)
{
// all items are equal
return 0;
}
void DeleteItem(LPDELETEITEMSTRUCT /*lpDeleteItemStruct*/)
{
// default - nothing
}
};
class SMenuODWnd : public SNativeWnd
,public SOwnerDraw<SMenuODWnd>
{
friend class SOwnerDraw<SMenuODWnd>;
public:
SMenuODWnd(HWND hMenuOwner,SMenuAttr * pMenuAttr);
~SMenuODWnd();
protected:
void OnInitMenu(HMENU menu);
void OnInitMenuPopup(HMENU menuPopup, UINT nIndex, BOOL bSysMenu);
void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);
void OnMenuSelect(UINT nItemID, UINT nFlags, HMENU menu);
LRESULT OnMenuChar(UINT nChar, UINT nFlags, HMENU hMenu);
BEGIN_MSG_MAP_EX(SMenuODWnd)
MSG_WM_INITMENU(OnInitMenu)
MSG_WM_INITMENUPOPUP(OnInitMenuPopup)
MSG_WM_MENUSELECT(OnMenuSelect)
CHAIN_MSG_MAP(SOwnerDraw<SMenuODWnd>)
REFLECT_NOTIFICATIONS_EX()
END_MSG_MAP()
HWND m_hMenuOwner;
SAutoRefPtr<SMenuAttr> m_attr;
};
class SOUI_EXP SMenu
{
public:
SMenu();
SMenu(const SMenu & src);
SMenu(HMENU hMenu);
~SMenu(void);
BOOL Attach(HMENU hMenu);
HMENU Detach();
BOOL LoadMenu(const SStringT & resId);
BOOL LoadMenu(pugi::xml_node xmlMenu);
void SetIconSkin(SAutoRefPtr<ISkinObj> icons);
/**
* SMenu::InsertMenu
* @brief 插入一个菜单项,参数和Windows API类似。
* @param int iIcon -- 显示的标图在iconSkin中的索引
* @param HICON hIcon -- 标图,默认为0,有值时,iIocn失效
* @return BOOL - TRUE:成功
*
* Describe hIcon会在菜单退出时自动调用DestroyIcon.
*/
BOOL InsertMenu(UINT uPosition, UINT uFlags, UINT_PTR nIDNewItem,LPCTSTR strText, int iIcon=-1,HICON hIcon=0);
BOOL AppendMenu(UINT uFlags,UINT_PTR uIDNewItem, LPCTSTR lpNewItem,int iIcon=-1,HICON hIcon=0);
BOOL CheckMenuItem(UINT uIdCheckItem, UINT uCheck);
BOOL DeleteMenu(UINT uPosition, UINT uFlags);
UINT TrackPopupMenu( UINT uFlags, int x, int y, HWND hWnd, LPCRECT prcRect=NULL, int nScale = 100);
void DestroyMenu();
BOOL ModifyMenuString(UINT uPosition, UINT uFlags,LPCTSTR lpItemString);
BOOL SetMenuUserData(UINT uPosition, UINT uFlags,ULONG_PTR ulUserData);
ULONG_PTR GetMenuUserData(UINT uPosition, UINT uFlags);
HMENU m_hMenu;
protected:
void UpdateScale(int nScale);
void BuildMenu(HMENU menuPopup,pugi::xml_node xmlNode);
void InitMenuItemData(SMenuItemData * itemInfo, const SStringW & strText);
void FreeMenuItemData(HMENU hMemu);
SMenuAttr * GetMenuAttr(HMENU hMenu) const;
void SetMenuAttr(HMENU hMenu,SMenuAttr *pMenuAttr) const;
bool m_bAttached;
SAutoRefPtr<ISkinObj> m_icons;
};
}//namespace SOUI