TFontDialog *FontDialog1;
void __fastcall FormCreate(TObject *Sender);
void __fastcall FormDestroy(TObject *Sender);
void __fastcall EnableFont1Click(TObject *Sender);
void __fastcall DisableFont1Click(TObject *Sender);
void __fastcall Font1Click(TObject *Sender);
private: // User declarations
//Working area for font size calculations
Graphics::TBitmap *WorkBitmap;
//Copy of the font menu item caption
String FontCaption;
//Message maps to tie windows events to certain functions
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_MEASUREITEM, TMessage, WMMeasureItem)
MESSAGE_HANDLER(WM_DRAWITEM, TMessage, WMDrawItem)
END_MESSAGE_MAP(TForm)
//Function to handle the WM_MEASUREITEM event
void __fastcall WMMeasureItem(TMessage& Message);
//Function to handle the WM_DRAWITEM event
void __fastcall WMDrawItem(TMessage& Message);
public: // User declarations
virtual __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
//.cpp文件
#include <vcl\vcl.h>
#pragma hdrstop
#include "FontMenuMain.h"
//---------------------------------------------------------------------------
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
//Initialize the working area
WorkBitmap = new Graphics::TBitmap;
//Initialize current font to the standard menu text color
FontDialog1->Font->Color = GetSysColor(COLOR_MENUTEXT);
//Tell windows that the menu item is owner-draw
ModifyMenu(MainMenu1->Handle, Font1->Command, MF_BYCOMMAND | MF_OWNERDRAW,
Font1->Command, NULL);
//Make a copy of the font caption
FontCaption = Font1->Caption;
//Add on the shortcut if there is one
if (Font1->ShortCut != 0)
FontCaption = FontCaption + "\t" + ShortCutToText(Font1->ShortCut);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
//Dispose of work area
WorkBitmap->Free();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::WMMeasureItem(TMessage& Message)
{
TMeasureItemStruct *Measures;
//Copy structure into a working variable for easy access
Measures = (TMeasureItemStruct *)(Message.LParam);
//Is message for a menu item?
if (Measures->CtlType == ODT_MENU)
{
//Is message for font menu item?
if (Measures->itemID == Font1->Command)
{
//Assign currently selected font to workspace
WorkBitmap->Canvas->Font = FontDialog1->Font;
//Calculate needed height for current font
Measures->itemHeight = WorkBitmap->Canvas->TextHeight(FontCaption);
//Calculate needed width
Measures->itemWidth = WorkBitmap->Canvas->TextWidth(FontCaption) +
GetSystemMetrics(SM_CXMENUCHECK);
//Tell Windows the event is handled
Message.Result = 1;
}
}
}
//----------------------------------------------------------------------------
void __fastcall TForm1::WMDrawItem(TMessage& Message)
{
HFONT OldFont;
TDrawItemStruct *DrawItem;
//Create a working variable for draw item structure
DrawItem = (TDrawItemStruct *)(Message.LParam);
//Is message for a menu item?
if (DrawItem->CtlType == ODT_MENU)
{
//Is message for the font menu item?
if (DrawItem->itemID == Font1->Command)
{
//Select current font into menu's device context
OldFont = SelectObject(DrawItem->hDC, FontDialog1->Font->Handle);
//Set correct background color
if ((DrawItem->itemState & ODS_SELECTED) != 0)
WorkBitmap->Canvas->Brush->Color = clHighlight;
else
WorkBitmap->Canvas->Brush->Color = clMenu;
//Paint the background
FillRect(DrawItem->hDC, &(DrawItem->rcItem),
WorkBitmap->Canvas->Brush->Handle);
//Adjust left bound of caption
DrawItem->rcItem.left += GetSystemMetrics(SM_CXMENUCHECK);
//Set text color according to state
if (((DrawItem->itemState & ODS_DISABLED) != 0) ||
((DrawItem->itemState & ODS_GRAYED) != 0))
{
//Use systems grayed color
SetTextColor(DrawItem->hDC, GetSysColor(COLOR_GRAYTEXT));
}
else if ((DrawItem->itemState & ODS_SELECTED) != 0)
{
//Use reverse of current font color
SetTextColor(DrawItem->hDC, ~FontDialog1->Font->Color);
}
else
{
//Use selected font color
SetTextColor(DrawItem->hDC, FontDialog1->Font->Color);
}
//Allow background color to surround characters
SetBkMode(DrawItem->hDC, TRANSPARENT);
//Draw the menu's caption
DrawText(DrawItem->hDC, FontCaption.c_str(), FontCaption.Length(),
&(DrawItem->rcItem), DT_TOP | DT_SINGLELINE | DT_EXPANDTABS);
//Release current font handle
SelectObject(DrawItem->hDC, OldFont);
//Tell windows the message is handled
Message.Result = 1;
}
}
}
void __fastcall TForm1::EnableFont1Click(TObject *Sender)
{
//Tell windows that the font command is enabled
ModifyMenu(MainMenu1->Handle, Font1->Command,
MF_BYCOMMAND | MF_ENABLED | MF_OWNERDRAW, Font1->Command, NULL);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::DisableFont1Click(TObject *Sender)
{
//Tell windows that the font command is disabled
ModifyMenu(MainMenu1->Handle, Font1->Command,
MF_BYCOMMAND | MF_GRAYED | MF_OWNERDRAW, Font1->Command, NULL);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Font1Click(TObject *Sender)
{
//Bring up the font dialog and check to see if the font was changed
if (FontDialog1->Execute())
//Fool windows into sending another WM_MEASUREITEM message
// so menu items can be sized for new font
ModifyMenu(MainMenu1->Handle, Font1->Command, MF_BYCOMMAND | MF_OWNERDRAW,
Font1->Command, NULL);