完善Borland C++ Builder可视化控件功能三例

原创 2003年07月15日 07:20:00

完善Borland C++ Builder可视化控件功能三例

王光红<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

笔者在编程中积累了点滴经验,与各位交流,共同提高。

一.        PageControlTabSheet“弹出来”

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />

弹出来的效果

CSDN_Dev_Image_2003-7-71422180.png

用过PageControl的人知道,PageControlActivePage的标头较“平坦”,没有“弹出”的立体效果,笔者经过改进达到了“弹出”的效果。

OnDrawTab事件中加入以下代码:

 

void __fastcall TSqlBuilderForm::PageControl1DrawTab(

      TCustomTabControl *Control, int TabIndex, const TRect &Rect,

      bool Active)

{

  Byte Red0,Red1,Green0,Green1,Blue0,Blue1;

 

  if(Active)

  {

 

    Red0 = 0;

    Red1 = 15;

    Green0 = 55;

    Green1 = 200;

Blue0 = 135;   

Blue1 = 240;

 

  }

  else

  {

    Red0 = 51;

    Red1 = 101;

    Green0 = 91;

    Green1 = 200;

    Blue0 = 91;

    Blue1 = 200;

  }

 

 

  int h;

  h = Rect.Bottom - Rect.Top - 2;

  Byte clr,clg,clb;

  int clTmp;

  int i = 0;

  float c=0.4; //亮的位置

  SetBkMode(Control->Canvas->Handle,TRANSPARENT);

 

  for(; i< h * c; ++i)

  {

    clTmp = Red0 + floor((double)i / double( h ) * (double)(Red1 - Red0) + 0.5) / c;

    if(clTmp < 0 ) clTmp  = 0 ;

    else if(clTmp > 255) clTmp  = 255;

    clr = Byte(clTmp);

 

    clTmp = Green0 + floor((double)i / double( h ) * (double)(Green1 - Green0) + 0.5) / c;

    if(clTmp < 0 ) clTmp  = 0 ;

    else if(clTmp > 255) clTmp  = 255;

    clg = Byte(clTmp);

 

    clTmp = Blue0 + floor((double)i / double( h ) * (double)(Blue1 - Blue0) + 0.5) / c;

    if(clTmp < 0 ) clTmp  = 0 ;

    else if(clTmp > 255) clTmp  = 255;

    clb = Byte(clTmp);

   

    Control->Canvas->Pen->Color = TColor(RGB(clr,clg,clb));

    Control->Canvas->MoveTo(Rect.Left  + 1,Rect.Top + i + 1 );

    Control->Canvas->LineTo(Rect.Right - 2,Rect.Top + i + 1 );

  }

 

    for( ; i< h ; ++i)

  {

    clTmp = Red0 + floor((double)(h-i) / double( h ) * (double)(Red1 - Red0) + 0.5);

    if(clTmp < 0 ) clTmp  = 0 ;

    else if(clTmp > 255) clTmp  = 255;

    clr = Byte(clTmp);

 

    clTmp = Green0 + floor((double)(h-i) / double( h ) * (double)(Green1 - Green0) + 0.5);

    if(clTmp < 0 ) clTmp  = 0 ;

    else if(clTmp > 255) clTmp  = 255;

    clg = Byte(clTmp);

 

    clTmp = Blue0 + floor((double)(h-i) / double( h ) * (double)(Blue1 - Blue0) + 0.5);

    if(clTmp < 0 ) clTmp  = 0 ;

    else if(clTmp > 255) clTmp  = 255;

    clb = Byte(clTmp);

    Control->Canvas->Pen->Color = TColor(RGB(clr,clg,clb));

    Control->Canvas->MoveTo(Rect.Left  + 1,Rect.Top + i + 1 );

    Control->Canvas->LineTo(Rect.Right - 2,Rect.Top + i + 1 );

  }

  AnsiString str = PageControl1->Pages[TabIndex]->Caption;

 

       int offset=0;

       if(PageControl1->Images!=NULL && ! Active ){

          Graphics::TBitmap * bmp = new Graphics::TBitmap;

          TImageList * img =dynamic_cast<TImageList*>( PageControl1->Images);

          img->GetBitmap(PageControl1->Pages[TabIndex]->ImageIndex,bmp);             Control->Canvas->Draw(Rect.Left+2,Rect.Top+1,bmp);

          offset= bmp->Width-10;

          delete bmp; bmp = NULL;

       }

 

 

 

Control->Canvas->TextOut( Rect.Left +offset + (Rect.Right - Rect.Left - Control->Canvas->TextWidth(str)) / 2,

                            Rect.Top + (Rect.Bottom - Rect.Top - Control->Canvas->TextHeight(str)) / 2,

                            str);

 

}

 

 

  

二.        StringGrid“画出”斑马线:

 

不同的颜色

CSDN_Dev_Image_2003-7-71422180.png

StringGrid的每一行都是一样的颜色,Cell多了容易看错位,我们可以在OnDrawCell事件中把相邻的Row之间“画出”不同的色彩,让人一目了然,不再会看花了眼。

 

void __fastcall TForm::StringGridDrawCell(TObject *Sender,

      int ACol, int ARow, TRect &Rect, TGridDrawState State)

{

TStringGrid * SG = dynamic_cast<TStringGrid *>(Sender);

 

 if(SG){

 try

    {

        if(ARow>=SG->FixedRows && ACol>=SG->FixedCols)

        {

            if(ARow%2 == 0)

            {

                SG->Canvas->Brush->Color=(TColor) 0x00E6FADC;

            }

            else

            {

                SG->Canvas->Brush->Color=(TColor)0x00FBEFD5;

            }

        }

        else{

                SG->Canvas->Font->Color = clBlack;

                SG->Canvas->Brush->Color=(TColor)0x00DDDDDD;

        }

 

        SG->Canvas->FillRect(Rect);

        DrawText(SG->Canvas->Handle, SG->Cells[ACol][ARow].c_str(), -1, (RECT*)&Rect, DT_SINGLELINE | DT_VCENTER | DT_CENTER);

    }

    catch(Exception &exception)

    {

        Application->ShowException(&exception);

        return ;

    }

    }

 

}

 

三.        ComboBox自动拉开菜单

使用ComboBox 时,您必须点击它的CSDN_Dev_Image_2003-7-71422184.png,下拉菜单才会打开,有点不方便。笔者继承ComboBox,制作了一个命名Autocombobox的控件,当鼠标进入Autocombobox区域,它会自动打开下拉菜单。

代码如下:

 

.h

//---------------------------------------------------------------------------

 

#ifndef AutoComboBoxH

#define AutoComboBoxH

//---------------------------------------------------------------------------

#include <SysUtils.hpp>

#include <Classes.hpp>

#include <Controls.hpp>

#include <StdCtrls.hpp>

//---------------------------------------------------------------------------

class PACKAGE TAutoComboBox : public TComboBox

{

private:

        TTimer *Timer;

        RECT r;

        void __fastcall NewComboBoxWP(TMessage &Msg);

        void __fastcall TimerTimer(TObject *Sender);

        void __fastcall (__closure *OldComboBoxWP)(TMessage &Message);

 

protected:

public:

        __fastcall TAutoComboBox(TComponent* Owner);

 

        __fastcall ~TAutoComboBox(void);

__published:

};

//---------------------------------------------------------------------------

#endif

 

//---------------------------------------------------------------------------

 

 

 

.cpp

#include <vcl.h>

 

#pragma hdrstop

 

#include "AutoComboBox.h"

#pragma package(smart_init)

//---------------------------------------------------------------------------

// ValidCtrCheck is used to assure that the components created do not have

// any pure virtual functions.

//

 

static inline void ValidCtrCheck(TAutoComboBox *)

{

        new TAutoComboBox(NULL);

}

//---------------------------------------------------------------------------

__fastcall TAutoComboBox::TAutoComboBox(TComponent* Owner)

        : TComboBox(Owner)

{

        Timer = new TTimer(this);

        Timer->Enabled=false;

        Timer->Interval=200;

        Timer->OnTimer=TimerTimer;

        OldComboBoxWP = this->WindowProc;

        this->WindowProc = NewComboBoxWP;

}

 

__fastcall TAutoComboBox::~TAutoComboBox(void)

{

delete Timer;

}

//---------------------------------------------------------------------------

namespace Autocombobox

{

        void __fastcall PACKAGE Register()

        {

                 TComponentClass classes[1] = {__classid(TAutoComboBox)};

                 RegisterComponents("WghSoft", classes, 0);

        }

}

//---------------------------------------------------------------------------

 

void __fastcall TAutoComboBox::TimerTimer(TObject *Sender)

{

        POINT pos;

        GetCursorPos(&pos);

        if(!(pos.x>r.left && pos.x<r.right && pos.y >r.top && pos.y < r.bottom)){

        this->DroppedDown=false;

        Timer->Enabled=false;

        }

}

//---------------------------------------------------------------------------

 

void __fastcall TAutoComboBox::NewComboBoxWP(TMessage& msg)

{

     switch (msg.Msg)

     {

        case CM_MOUSEENTER:

        {

        this->DroppedDown=true;

        msg.Result = true;

        break;

        }

        case CM_MOUSELEAVE:

        {

        POINT pos;

        Timer->Enabled=true;

        GetCursorPos(&pos);

        this->Perform(CB_GETDROPPEDCONTROLRECT,0,LPARAM(&r));

        if(!(pos.x>r.left && pos.x<r.right && pos.y >r.top && pos.y < r.bottom)){

                        this->DroppedDown=false;

                        Timer->Enabled=false;

                        }

           msg.Result = true;

           break;

         }

         case WM_DESTROY:

         {

 

            break;

         }

     }

    OldComboBoxWP(msg);

}

pagecontrol控件的各种使用方法

C++Builder提供了几种功能相似的多页组件,它们是:Win32页中的TabControl,PageControl组件,Win31页中的TabSet和TabbedNoteBook组件。从它们所在的...
  • Lixinag
  • Lixinag
  • 2008年01月13日 12:33
  • 11458

如何在C++Builder中使用Delphi控件

使C++Builder使用DelphiVCL类库的方法基于Windows中较通用的DLL方式。在实际应用中找到了将 VCL控件转化为DLL库,在C++Builder动态调用DLL。此法适用于非可视V...
  • hemeinvyiqiluoben
  • hemeinvyiqiluoben
  • 2014年09月20日 17:24
  • 509

c++builder使用Windows系统提供的IP控件

本文是ccrun(老妖)根据偶然间看到的一篇文章略作修改而成。参考资料: 标题:在Delphi中使用IP控件 作者:西安交通大学9649# 刘明华 在些对原作者的无私奉献表示感谢!如欲转载请保留...
  • lz465350
  • lz465350
  • 2014年11月12日 10:45
  • 626

C++Builder中使用MSCOMM进行串口编程

一、引言             目前,在用计算机进行数据传输时,常用的是串行通信方式。用C++   Builder来编写串行通信程序时,可以调用Windows   API函数,也可以利用VB中的...
  • xuecall
  • xuecall
  • 2014年09月04日 10:42
  • 1838

C++ builder 6 安装第三方控件的中遇到的问题及解决

新装C++ builder 6后,安装第三方控件时,往往不能成功安装,出现很多问题,这里记录我在安装过程中遇到的一些问题及解决方案: 1、编译时出现错误提示:Unable to open file '...
  • JohnnyHu90
  • JohnnyHu90
  • 2014年02月21日 21:47
  • 3465

C++builder自绘控件框架

#ifndef __switch1__ #define __switch1__ #include "gdi.h" //自定义GDI+函数库 class TSwitchButton : public...
  • chinayu2007
  • chinayu2007
  • 2015年09月06日 15:28
  • 982

在C++ Builder中用socket api来写网络通讯程序(同时支持TCP和UDP协议)

在7月4日看完sockcomp.pas后,我决定用socket api来写一个客户端和服务器并且同时支持TCP,UDP协议,于是我就去做,现将代码贴出来(已调试通过) Socket api Clie...
  • enjoy0104
  • enjoy0104
  • 2015年04月21日 01:05
  • 1082

使用 C++ Builder 创建应用程序

3.1 创建应用程序 C++Builder的主要用途于设计创建Windows应用程序。有三种基本的Windows应用程序: · WindowsGUI应用程序。 · 控制面板应用程序。 · 服务应用程序...
  • u010984552
  • u010984552
  • 2016年08月19日 20:18
  • 2050

C++ builder 添加资源文件

最近在研究BCB中资源文件的嵌入,找到一些资料,整理了一下,写下来供参考。    资源文件是一个以.rc结尾的文本文件,RC是资源脚本(Resource   Script)的意思,它的格式很简单,每...
  • Anton8801
  • Anton8801
  • 2016年05月20日 14:03
  • 923

c++builder向c#开发的webservice传递非数字参数

一、引用WebService地址 BCB6.0环境下,File-New-Other-WebService-WSDL Importer。然后手动写完整地址。如:“http://192.168.1....
  • u010000723
  • u010000723
  • 2013年08月17日 10:46
  • 279
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:完善Borland C++ Builder可视化控件功能三例
举报原因:
原因补充:

(最多只允许输入30个字)