ownerdrw.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 494 行 · 第 1/2 页
CPP
494 行
///////////////////////////////////////////////////////////////////////////////
// Name: msw/ownerdrw.cpp
// Purpose: implementation of wxOwnerDrawn class
// Author: Vadim Zeitlin
// Modified by:
// Created: 13.11.97
// RCS-ID: $Id: ownerdrw.cpp,v 1.62.2.2 2006/01/18 16:32:49 JS Exp $
// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma implementation
#endif
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#include "wx/msw/private.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/window.h"
#include "wx/msw/private.h"
#include "wx/font.h"
#include "wx/bitmap.h"
#include "wx/dcmemory.h"
#include "wx/menu.h"
#include "wx/utils.h"
#endif
#include "wx/settings.h"
#include "wx/ownerdrw.h"
#include "wx/menuitem.h"
#include "wx/fontutil.h"
#include "wx/module.h"
#if wxUSE_OWNER_DRAWN
#ifndef SPI_GETKEYBOARDCUES
#define SPI_GETKEYBOARDCUES 0x100A
#endif
class wxMSWSystemMenuFontModule : public wxModule
{
public:
virtual bool OnInit()
{
ms_systemMenuFont = new wxFont;
#if defined(__WXMSW__) && defined(__WIN32__) && defined(SM_CXMENUCHECK)
NONCLIENTMETRICS nm;
nm.cbSize = sizeof(NONCLIENTMETRICS);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS,0,&nm,0);
ms_systemMenuButtonWidth = nm.iMenuHeight;
ms_systemMenuHeight = nm.iMenuHeight;
// create menu font
wxNativeFontInfo info;
memcpy(&info.lf, &nm.lfMenuFont, sizeof(LOGFONT));
ms_systemMenuFont->Create(info);
if (SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &ms_showCues, 0) == 0)
ms_showCues = true;
#endif
return true;
}
virtual void OnExit()
{
delete ms_systemMenuFont;
ms_systemMenuFont = NULL;
}
static wxFont* ms_systemMenuFont;
static int ms_systemMenuButtonWidth; // windows clean install default
static int ms_systemMenuHeight; // windows clean install default
static bool ms_showCues;
private:
DECLARE_DYNAMIC_CLASS(wxMSWSystemMenuFontModule)
};
// these static variables are from the wxMSWSystemMenuFontModule object
// and reflect the system settings returned by the Win32 API's
// SystemParametersInfo() call.
wxFont* wxMSWSystemMenuFontModule::ms_systemMenuFont = NULL;
int wxMSWSystemMenuFontModule::ms_systemMenuButtonWidth = 18; // windows clean install default
int wxMSWSystemMenuFontModule::ms_systemMenuHeight = 18; // windows clean install default
bool wxMSWSystemMenuFontModule::ms_showCues = true;
IMPLEMENT_DYNAMIC_CLASS(wxMSWSystemMenuFontModule, wxModule)
// temporary hack to implement wxOwnerDrawn::IsMenuItem() without breaking
// backwards compatibility
#if wxCHECK_VERSION(2, 7, 0)
#pragma warning "TODO: remove gs_menuItems hack"
#endif
// VC++ 6 gives a warning here:
//
// return type for 'OwnerDrawnSet_wxImplementation_HashTable::iterator::
// operator ->' is 'class wxOwnerDrawn ** ' (ie; not a UDT or reference to
// a UDT. Will produce errors if applied using infix notation.
//
// shut it down
#ifdef __VISUALC__
#if __VISUALC__ <= 1300
#pragma warning(push)
#pragma warning(disable: 4284)
#define POP_WARNINGS
#endif
#endif
#include "wx/hashset.h"
WX_DECLARE_HASH_SET(wxOwnerDrawn*, wxPointerHash, wxPointerEqual, OwnerDrawnSet);
#ifdef POP_WARNINGS
#pragma warning(pop)
#endif
static OwnerDrawnSet gs_menuItems;
// ============================================================================
// implementation of wxOwnerDrawn class
// ============================================================================
// ctor
// ----
wxOwnerDrawn::wxOwnerDrawn(const wxString& str,
bool bCheckable,
bool bMenuItem)
: m_strName(str)
{
if (ms_nDefaultMarginWidth == 0)
{
ms_nDefaultMarginWidth = ::GetSystemMetrics(SM_CXMENUCHECK) +
wxSystemSettings::GetMetric(wxSYS_EDGE_X);
ms_nLastMarginWidth = ms_nDefaultMarginWidth;
}
m_bCheckable = bCheckable;
m_bOwnerDrawn = false;
m_nHeight = 0;
m_nMarginWidth = ms_nLastMarginWidth;
m_nMinHeight = wxMSWSystemMenuFontModule::ms_systemMenuHeight;
m_bmpDisabled = wxNullBitmap;
// TODO: we can't add new m_isMenuItem field in 2.6, so we use this hack
// with the map, but do add m_isMenuItem in 2.7
if ( bMenuItem )
{
gs_menuItems.insert(this);
}
}
wxOwnerDrawn::~wxOwnerDrawn()
{
// TODO: remove this in 2.7
gs_menuItems.erase(this);
}
bool wxOwnerDrawn::IsMenuItem() const
{
// TODO: in 2.7, replace this with simple "return m_isMenuItem"
// some versions of mingw have problems without const_cast when wxUSE_STL=1
return gs_menuItems.count(wx_const_cast(wxOwnerDrawn *, this)) == 1;
}
// these items will be set during the first invocation of the c'tor,
// because the values will be determined by checking the system settings,
// which is a chunk of code
size_t wxOwnerDrawn::ms_nDefaultMarginWidth = 0;
size_t wxOwnerDrawn::ms_nLastMarginWidth = 0;
// drawing
// -------
wxFont wxOwnerDrawn::GetFontToUse() const
{
wxFont font = m_font;
if ( !font.Ok() )
{
if ( IsMenuItem() )
font = *wxMSWSystemMenuFontModule::ms_systemMenuFont;
if ( !font.Ok() )
font = *wxNORMAL_FONT;
}
return font;
}
// get size of the item
// The item size includes the menu string, the accel string,
// the bitmap and size for a submenu expansion arrow...
bool wxOwnerDrawn::OnMeasureItem(size_t *pwidth, size_t *pheight)
{
if ( IsOwnerDrawn() )
{
wxMemoryDC dc;
wxString str = wxStripMenuCodes(m_strName);
// if we have a valid accel string, then pad out
// the menu string so that the menu and accel string are not
// placed on top of each other.
if ( !m_strAccel.empty() )
{
str.Pad(str.Length()%8);
str += m_strAccel;
}
dc.SetFont(GetFontToUse());
dc.GetTextExtent(str, (long *)pwidth, (long *)pheight);
// add space at the end of the menu for the submenu expansion arrow
// this will also allow offsetting the accel string from the right edge
*pwidth += GetMarginWidth() + 16;
}
else // don't draw the text, just the bitmap (if any)
{
*pwidth =
*pheight = 0;
}
// increase size to accommodate bigger bitmaps if necessary
if (m_bmpChecked.Ok())
{
// Is BMP height larger then text height?
size_t adjustedHeight = m_bmpChecked.GetHeight() +
2*wxSystemSettings::GetMetric(wxSYS_EDGE_Y);
if (*pheight < adjustedHeight)
*pheight = adjustedHeight;
const size_t widthBmp = m_bmpChecked.GetWidth();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?