如何在标题栏上加按钮?

shiningstar 2001-06-12 04:55:00
加精
请教各位高手,不胜感激!!
...全文
101 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
shiningstar 2001-06-21
  • 打赏
  • 举报
回复
谢谢各位了
SSTS 2001-06-12
  • 打赏
  • 举报
回复
头文件
//---------------------------------------------------------------------------
#ifndef MAINFORMH
#define MAINFORMH
//---------------------------------------------------------------------------
#include <vcl\Classes.hpp>
#include <vcl\Controls.hpp>
#include <vcl\StdCtrls.hpp>
#include <vcl\Forms.hpp>
#include <vcl\Menus.hpp>
#include <vcl\ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TMainMenu *MainMenu1;
TMenuItem *File1;
TMenuItem *Exit1;
TTimer *Timer1;
void __fastcall Exit1Click(TObject *Sender);
void __fastcall Timer1Timer(TObject *Sender);
void __fastcall FormResize(TObject *Sender);
private: // User declarations
TCanvas *WindowCanvas;
TRect CaptionRect;
AnsiString CustomCaption;
TColor FinalCaptionColor;
int FinalBlueIntensity;
int FinalGreenIntensity;
int FinalRedIntensity;
bool IsNT35;
bool HeartBeat;
bool CanDrawMyCustomCaption(void);
void CalculateCaptionRect(void);
void DrawGradient(void);
void DrawIcon(void);
void DrawCaptionString(void);
void DrawHeartBeatLight(void);
void __fastcall WMNCPaint(TMessage &Msg);
void __fastcall WMNCActivate(TWMNCActivate &Msg);
public: // User declarations
__fastcall TForm1(TComponent* Owner);
__fastcall ~TForm1(void);
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_NCPAINT,TMessage,WMNCPaint)
MESSAGE_HANDLER(WM_NCACTIVATE,TWMNCActivate,WMNCActivate)
END_MESSAGE_MAP(TForm)
};
//---------------------------------------------------------------------------
extern TForm1 *Form1;
//---------------------------------------------------------------------------
#endif



//---------------------------------------------------------------------------
#include <vcl\vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
USEFORM("MAINFORM.cpp", Form1);
USERES("TITLEBAR.res");
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
Application->Initialize();
Application->CreateForm(__classid(TForm1), &Form1);
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
return 0;
}
//-----------------------------


//---------------------------------------------------------------------------
#include <vcl\vcl.h>
#pragma hdrstop

#include "MAINFORM.h"
//---------------------------------------------------------------------------
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
CustomCaption = "Custom Caption";
Caption = "";
WindowCanvas = new TCanvas;
// this code determines if we are running on NT3.X
TOSVersionInfo ver;
ver.dwOSVersionInfoSize = sizeof(TOSVersionInfo);
GetVersionEx( &ver);
if(ver.dwMajorVersion < 4)
{
// if the OS is NT 3.5, the custom caption won't be drawn
// use the Caption property as usual, since the custom
// caption won't be able to draw the string.
IsNT35 = true;
Caption = CustomCaption;
}
else
IsNT35 = false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Exit1Click(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::WMNCActivate(TWMNCActivate &Msg)
{
Msg.Result = true; // always handle this message;
if ((bool)Msg.Active == false) // if non-active draw default
{ // non-active title bar
DefWindowProc( Handle, Msg.Msg, Msg.Active, 0 );
// add code here to draw caption when window is inactive.
// in this example, we leave the inactive caption alone.
return;
}
TMessage PaintMsg; // if active, do same thing as WMNCPaint
PaintMsg.Msg = Msg.Msg; // create a MSG to pass to WMNCPaint and
PaintMsg.WParam = Msg.Active; // call the function directly so painting
WMNCPaint(PaintMsg); // happens now.
}

void __fastcall TForm1::WMNCPaint(TMessage &Msg)
{
// use default processing to draw min/max/close buttons, menu, and the
// frame. the caption bar is drawn too, but we paint over that later.
DefWindowProc(Handle, Msg.Msg,Msg.WParam,Msg.LParam);

// Check for any reason not to draw the custom caption
if(CanDrawMyCustomCaption() == false)
return;

// create a DC for the entire window, then assign
// the handle to the window canvas
HDC WindowDC = GetWindowDC(Handle);
WindowCanvas->Handle = WindowDC;

CalculateCaptionRect(); // calculate size of caption bar
DrawGradient(); // draw the shaded gradient
DrawIcon(); // patch the icon
DrawCaptionString();
DrawHeartBeatLight(); // draw the LED heartbeat

ReleaseDC(Handle, WindowDC); // free resources
WindowCanvas->Handle = 0;
}

bool TForm1::CanDrawMyCustomCaption(void)
{
// under certain conditions we don't want to shade the custom caption.
// this function bundles all of the reasons into one.
if (WindowCanvas == 0) // WMNCPaint can execute after
return false; // destructor has been called.
if(Application->Active == false) //can get WM_NCPAINT messages
return false; // when inactive
if(Width < 150) // shading looks poor at very small
return false; // widths
if(IsNT35 == true) // NT has 3.5 has win3 style system menu
return false; // and centered caption text, so forget it

// shading looks poor if its from black to a very light color, Word actually
// shades from white instead of black for light caption colors, we will just not
// shade for light colored captions. Light colors have high RGB values
FinalCaptionColor = TColor(GetSysColor(COLOR_ACTIVECAPTION));
FinalBlueIntensity = GetBValue(FinalCaptionColor);
FinalGreenIntensity= GetGValue(FinalCaptionColor);
FinalRedIntensity = GetRValue(FinalCaptionColor);
// is at least one of the RGB values dark, if not, don't draw the shading
if ((FinalBlueIntensity < 128) || (FinalGreenIntensity < 128) || (FinalRedIntensity < 128) )
return true;
else
return false;
}

void TForm1::CalculateCaptionRect(void)
{
// determine the coordinates of the custom area of the caption. The left, top,
// and bottom must be calculated precisely. The right value is an arbitrary
// value that keeps us away from the min/max buttons.
CaptionRect.Left = GetSystemMetrics(SM_CXFRAME);
CaptionRect.Right= Width- 4*GetSystemMetrics(SM_CXSIZE); // stay away from btns
CaptionRect.Top = GetSystemMetrics(SM_CYFRAME);
CaptionRect.Bottom=CaptionRect.Top + GetSystemMetrics(SM_CYCAPTION)-1;
}


void TForm1::DrawGradient(void)
{
// Shading involves gradually increasing RGB color values from 0 (black)
// to the final RGB value of the caption color. The Increment values
// will be multiplied by 0,1..31 to create 32 shades. The FinalXXX
// values are calculated inside of CanDrawMyCustomGraphics
int BlueIncrement = (FinalBlueIntensity+1) / 32; // max intensity is 255,
int GreenIncrement= (FinalGreenIntensity+1)/32; // adding 1 makes number
int RedIncrement = (FinalRedIntensity+1)/32; // evenly divisible by 32.

TRect Section = CaptionRect;
// SectionWidth represents the width of each gradient section. Caption
// bar will contain 36 gradient sections, 5 sections will be black, the
// remaining 31 sections will be between black and the caption color
int SectionWidth = (CaptionRect.Right - CaptionRect.Left)/36;
TColor FillColor(clBlack);
Section.Right = Section.Left + 5*SectionWidth; //draw 5 sections of black
WindowCanvas->Brush->Color = FillColor; //configure the brush
WindowCanvas->Brush->Style = bsSolid;
WindowCanvas->FillRect(Section); //fill in black sections
Section.Left+=5*SectionWidth; //move section over

for (int j=1;j<=31;j++) // loop through the shades of color
{ // from black to the caption color
Section.Right = Section.Left + SectionWidth; // size the section
FillColor = (TColor) RGB((RedIncrement*j), // create dithered color
(GreenIncrement*j), // based on loop index.
(BlueIncrement*j));
WindowCanvas->Brush->Color = FillColor; // set brush to new color
WindowCanvas->FillRect(Section); // brush fill the section
Section.Left += SectionWidth; // move section over
}
}


void TForm1::DrawIcon(void)
{
// Need to redraw the system icon because DrawGradient just painted
// over it with black. DrawGradient painted over it because the icon
// had the caption color surrounding it.
int IconWidth = GetSystemMetrics(SM_CXSMICON); // calculate width and
int IconHeight= GetSystemMetrics(SM_CYSMICON); // height of icon
TRect Section;
Section.Left=CaptionRect.Left+2; // determine where the icon belongs
Section.Top =CaptionRect.Top +1;
Section.Right=Section.Left + IconWidth; // size the rect to hold the icon
Section.Bottom=Section.Top + IconHeight;

// paint the application icon, could avoid stretching by
// supplying a 16 by 16 icon.
DrawIconEx(WindowCanvas->Handle, Section.Left, Section.Top, // api call
Application->Icon->Handle,IconWidth,IconHeight,0,NULL,DI_NORMAL);
}


void TForm1::DrawCaptionString(void)
{
// need to draw our own caption string. must avoid using the Caption
// form member to avoid flicker
RECT r; // need an API style rect
r.left=CaptionRect.Left + 2 + 16 + 4; // size the rect
r.right=CaptionRect.Right-20;
r.top = CaptionRect.Top;
r.bottom = CaptionRect.Bottom;
SetBkMode(WindowCanvas->Handle,TRANSPARENT); // transparent mode so text
WindowCanvas->Font->Color=clWhite; // does not wipe out shading
WindowCanvas->Font->Style = WindowCanvas->Font->Style << fsBold;
DrawText(WindowCanvas->Handle,CustomCaption.c_str(),CustomCaption.Length(),
&r,DT_SINGLELINE|DT_VCENTER); // draw with vert centered text
}


void TForm1::DrawHeartBeatLight(void)
{
// draw a little LED style heartbeat indicator. this is just an
// ellipse with varying fill color
TRect Section = CaptionRect;
int cYCaption = GetSystemMetrics(SM_CYCAPTION);
if(HeartBeat == true)
WindowCanvas->Brush->Color = (TColor) RGB(0,255,0); // bright green
else
WindowCanvas->Brush->Color = clBlack;
WindowCanvas->Pen->Color=clBlack;
WindowCanvas->Ellipse(Section.Right-cYCaption/2,
Section.Top +cYCaption/4,
Section.Right,
Section.Bottom-cYCaption/4);
}

__fastcall TForm1::~TForm1(void)
{
delete WindowCanvas;
WindowCanvas = 0; // zero canvas so CanDrawMyCustomCaption can
// block use of an invalid pointer.
}

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
HeartBeat = !HeartBeat;
Perform(WM_NCPAINT,1,0);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormResize(TObject *Sender)
{
Perform(WM_NCPAINT,1,0);
}
//---------------------------------------------------------------------------
这个程序不是我的,但给你参考一下。。
SSTS 2001-06-12
  • 打赏
  • 举报
回复
标题栏上不得真正的加按钮。。
必须自已画,包括按下时的壮态等等。。。。
我不懂电脑 2001-06-12
  • 打赏
  • 举报
回复
有编文章说过,大意是标题上的不是真正的按钮组件,而是在标题栏上画一个按钮形状,再处理标题的鼠标按键事件。
sundayboys 2001-06-12
  • 打赏
  • 举报
回复
up
rh 2001-06-12
  • 打赏
  • 举报
回复
我只知道自画方法

13,825

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧