Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Класс-заменитель стандартного свойства Hint 
:(
    Опции темы
mr.Anderson
Дата 5.4.2007, 13:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


iOS Lead Developer
****


Профиль
Группа: Участник Клуба
Сообщений: 3374
Регистрация: 20.12.2004
Где: далеко

Репутация: 3
Всего: 128



Вот написал класс для замены стандартного свойства Hint у компонентов Билдера. Мне не нравилось то, что нельзя увеличить задержку Hint'а, нельзя настроить его стиль. Поэтому решил написать свой класс для этих целей.

Плюсы:
[+] В перспективе - настраиваемая задержка хинта. Пока она не реализована, поэтому хинт отображается бесконечно долго (пока не уберешь мышь с компонента, для которого вызывается хинт).
[+] Настраиваемый стиль хинта.
[+] Хинт перемещается вслед за указателем мыши.

Минусы:
[-] Высокая загрузка ЦП ( 40% ) при движении мышью по компоненту.
[-] Насильное переопределение виртуального метода AppMsg (нужно для управления перемещением хинта за указателем). Как я понимаю, это помешает юзеру определить собственный метод в программе при использовании данного класса.

Вот, собственно, код. С настройкой задержки пока напряг (все, с ней связанное, в коде пока закомментировано). В остальном все сделано и работает (проверено).
Хотелось бы услышать ваши комментарии. Можно что-нить предложить, я постараюсь реализовать. Можно критиковать. smile Только плз не предлагайте обработку ошибок - это я еще не сделал, но делать буду.
Код

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

#ifndef VCL_H
#define VCL_H
#endif
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------

enum TAllowedFonts { afArial, afBookAntiqua, afBookmanOldStyle,
                     afComicSansMS, afCourier, afCourierNew,
                     afFixedsys, afGOSTtypeA, afImpact, afLucidaConsole,
                     afLucidaSansUnicode, afMonotypeCorsiva, afMSSansSerif,
                     afSystem, afTerminal, afTimesNewRoman };
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------

class TPanelHint {
 public:
  __fastcall TPanelHint( TPanel *, void * = IDC_HAND, unsigned short = 0 );
  __fastcall TPanelHint( TPanel *, TColor, TColor, TAllowedFonts, TFontStyles, void *, unsigned short );
  virtual __fastcall ~TPanelHint( void );

  void __fastcall Show( void );
  void __fastcall Hide( void );
  inline bool __fastcall GetVisibility( void )
   { return this->PSrc->Visible; }

  TPanelHint & __fastcall SetCaption( AnsiString );
  inline AnsiString __fastcall GetCaption( void )
   { return this->LSrcCaption->Caption; }

  TPanelHint & __fastcall SetBackColor( TColor );
  inline TColor __fastcall GetBackColor( void )
   { return this->PSrc->Color; }

  TPanelHint & __fastcall SetFontColor( TColor );
  inline TColor __fastcall GetFontColor( void )
   { return this->LSrcCaption->Font->Color; }

  TPanelHint & __fastcall SetFontName( TAllowedFonts );
  inline AnsiString __fastcall GetFontName( void )
   { return this->LSrcCaption->Font->Name; }
  inline TAllowedFonts __fastcall GetFontNameAF( void )
   { return this->Convert( this->LSrcCaption->Font->Name ); }

  TPanelHint & __fastcall SetFontStyle( TFontStyles );
  inline TFontStyles __fastcall GetFontStyle( void )
   { return this->LSrcCaption->Font->Style; }

 // TPanelHint & __fastcall SetDelay( unsigned short );
 /* inline unsigned short __fastcall GetDelay( void )
   { return this->delay; } */

  TPanelHint & __fastcall SetCursorIdentifier( void * );
  TPanelHint & __fastcall SetCursorPosition( int, int );
  TPanelHint & __fastcall SetCursorPosition( tagPOINT );
  inline TPoint __fastcall GetCursorPosition( void )
   { return this->curPos; }

  virtual void __fastcall AppMsg( TMsg &, bool & );

 private:
  TPanel *PSrc;
  TLabel *LSrcCaption;
 // TTimer *TMR;
  void *curIdentifier;
  tagPOINT curPos;

  AnsiString __fastcall Convert( TAllowedFonts );
  TAllowedFonts __fastcall Convert( AnsiString );

  void __fastcall CreateCaption( void );
 // void __fastcall CreateTimer( void );
  void __fastcall SetHintPosition( void );
  void __fastcall CalculateCaptionPos( void );
  void __fastcall CalculateSize( void );

 // void __fastcall OnTimer( TObject * );
};
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------

__fastcall TPanelHint::TPanelHint( TPanel *P, void *cursorIdentifier,
                                   unsigned short DelaySeconds )
{
 this->PSrc = P;
 this->PSrc->Caption = "";

 this->CreateCaption();

// this->CreateTimer();
// this->SetDelay( DelaySeconds * 1000 );

 this->curIdentifier = cursorIdentifier;

 Application->OnMessage = AppMsg;
}
//---------------------------------------------------------------------------

__fastcall TPanelHint::TPanelHint( TPanel *P, TColor BackColor,
                                   TColor FontColor, TAllowedFonts FontName,
                                   TFontStyles FontStyle, void * cursorIdentifier,
                                   unsigned short DelaySeconds )
{
 this->PSrc = P;
 this->PSrc->Caption = "";
 this->PSrc->Color = BackColor;
 this->PSrc->Font->Color = FontColor;
 this->PSrc->Font->Name = this->Convert( FontName );
 this->PSrc->Font->Style = FontStyle;

 this->CreateCaption();

 this->curIdentifier = cursorIdentifier;

// this->CreateTimer();
// this->SetDelay( DelaySeconds * 1000 );

 Application->OnMessage = this->AppMsg;
}
//---------------------------------------------------------------------------

__fastcall TPanelHint::~TPanelHint( void )
{
 delete this->PSrc;
 delete this->LSrcCaption;
// delete this->TMR;
}
//---------------------------------------------------------------------------

void __fastcall TPanelHint::Show( void )
{
 if( this->GetCaption().IsEmpty() )
  return;

 GetCursorPos( &curPos );
 this->SetHintPosition();
 this->PSrc->Visible = true;

// if( this->GetDelay() )
 // this->TMR->Enabled = true;
}
//---------------------------------------------------------------------------

void __fastcall TPanelHint::Hide( void )
{
 this->PSrc->Visible = false;
}
//---------------------------------------------------------------------------

TPanelHint & __fastcall TPanelHint::SetCaption( AnsiString Caption )
{
 this->LSrcCaption->Caption = Caption;
 this->CalculateCaptionPos();

 return *this;
}
//---------------------------------------------------------------------------

TPanelHint & __fastcall TPanelHint::SetBackColor( TColor Color )
{
 this->PSrc->Color = Color;

 return *this;
}
//---------------------------------------------------------------------------

TPanelHint & __fastcall TPanelHint::SetFontColor( TColor Color )
{
 this->LSrcCaption->Font->Color = Color;

 return *this;
}
//---------------------------------------------------------------------------

TPanelHint & __fastcall TPanelHint::SetFontName( TAllowedFonts FontName )
{
 this->LSrcCaption->Font->Name = this->Convert( FontName );

 return *this;
}
//---------------------------------------------------------------------------

TPanelHint & __fastcall TPanelHint::SetFontStyle( TFontStyles FontStyle )
{
 this->LSrcCaption->Font->Style = FontStyle;

 return *this;
}
//---------------------------------------------------------------------------

/*TPanelHint & __fastcall TPanelHint::SetDelay( unsigned short Delay )
{
 this->delay = Delay;
 this->TMR->Interval = Delay;

 return *this;
}*/
//---------------------------------------------------------------------------

TPanelHint & __fastcall TPanelHint::SetCursorIdentifier( void *Identifier )
{
 this->curIdentifier = Identifier;

 return *this;
}
//---------------------------------------------------------------------------

TPanelHint & __fastcall TPanelHint::SetCursorPosition( int X, int Y )
{
 this->curPos.x = X;
 this->curPos.y = Y;

 if( this->GetVisibility() )
  this->SetHintPosition();

 return *this;
}
//---------------------------------------------------------------------------

TPanelHint & __fastcall TPanelHint::SetCursorPosition( tagPOINT Position )
{
 this->curPos = Position;

 if( this->GetVisibility() )
  this->SetHintPosition();

 return *this;
}
//---------------------------------------------------------------------------

void __fastcall TPanelHint::AppMsg( TMsg &Msg, bool &Handle )
{
 if( ( Msg.message == WM_MOUSEMOVE ) &&
     ( GetCursor() == this->curIdentifier ) ) {
  if( this->GetVisibility() ) {
   GetCursorPos( &(this->curPos) );
   this->SetHintPosition();
   this->PSrc->Parent->Repaint();
  }
 }
}
//---------------------------------------------------------------------------

AnsiString __fastcall TPanelHint::Convert( TAllowedFonts FontName )
{
 switch( FontName ) {
  case afArial: return "Arial";
  case afBookAntiqua: return "Book Antiqua";
  case afBookmanOldStyle: return "Bookman Old Style";
  case afCourier: return "Courier";
  case afCourierNew: return "Courier New";
  case afFixedsys: return "Fixedsys";
  case afGOSTtypeA: return "GOST type A";
  case afLucidaConsole: return "Lucida Console";
  case afLucidaSansUnicode: return "Lucida Sans Unicode";
  case afMonotypeCorsiva: return "Monotype Corsiva";
  case afMSSansSerif: return "MS Sans Serif";
  case afSystem: return "System";
  case afTerminal: return "Terminal";
  case afTimesNewRoman: return "Times New Roman";
  default: break;
 }

 return "";
}
//---------------------------------------------------------------------------

TAllowedFonts __fastcall TPanelHint::Convert( AnsiString FontName )
{
 if( FontName == "Arial" ) return afArial;
 if( FontName == "Book Antiqua" ) return afBookAntiqua;
 if( FontName == "Bookman Old Style" ) return afBookmanOldStyle;
 if( FontName == "Courier" ) return afCourier;
 if( FontName == "Courier New" ) return afCourierNew;
 if( FontName == "Fixedsys" ) return afFixedsys;
 if( FontName == "GOST type A" ) return afGOSTtypeA;
 if( FontName == "Lucida Console" ) return afLucidaConsole;
 if( FontName == "Lucida Sans Unicode" ) return afLucidaSansUnicode;
 if( FontName == "Monotype Corsiva" ) return afMonotypeCorsiva;
 if( FontName == "MS Sans Serif" ) return afMSSansSerif;
 if( FontName == "System" ) return afSystem;
 if( FontName == "Terminal" ) return afTerminal;
 if( FontName == "Times New Roman" ) return afTimesNewRoman;

 return afArial; //избегаем билдеровского предупреждения
}
//---------------------------------------------------------------------------

void __fastcall TPanelHint::CreateCaption( void )
{
 this->LSrcCaption = new TLabel( this->PSrc );
 this->LSrcCaption->Parent = this->PSrc;
 this->LSrcCaption->Transparent = true;
}
//---------------------------------------------------------------------------

/*void __fastcall TPanelHint::CreateTimer( void )
{
 this->TMR = new TTimer( this->PSrc );
 this->TMR->Enabled = false;
 this->TMR->OnTimer = this->OnTimer;
}*/
//---------------------------------------------------------------------------

void __fastcall TPanelHint::SetHintPosition( void )
{
 this->PSrc->Left = this->curPos.x + 10;
 this->PSrc->Top = this->curPos.y + 15;
}
//---------------------------------------------------------------------------

void __fastcall TPanelHint::CalculateCaptionPos( void )
{
 this->CalculateSize();

 this->LSrcCaption->Left = this->PSrc->Width / 2 - this->LSrcCaption->Width / 2;
 this->LSrcCaption->Top = this->PSrc->Height / 2 - this->LSrcCaption->Height / 2;
}
//---------------------------------------------------------------------------

void __fastcall TPanelHint::CalculateSize( void )
{
 this->PSrc->Width = this->LSrcCaption->Width + 30;
 this->PSrc->Height = this->LSrcCaption->Height + 10; 
}
//---------------------------------------------------------------------------

/*void __fastcall TPanelHint::OnTimer( TObject *Sender )
{
 this->Hide();
 this->TMR->Enabled = false;
}*/
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------

Использование класса:

1. Объявляем глобальную переменную класса:
Код

TPanelHint *Hnt;

2. Кидаем на форму панель (TPanel). Называем ее (например, PHint).
3. В OnShow формы добавляем инициализирующие операторы:
Код

Hnt = new TPanelHint( PHint );
//задаем указатель курсора, по которому класс при перемещении мыши понимает, что хинт пора убирать (по умолчанию установлен в IDC_HAND, так что можно и не устанавливать)
Hnt->SetCursorIdentifier( IDC_HAND );
//задаем общий стиль по своему усмотрению
Hnt->SetBackColor( clBlack ).SetFontColor( clWhite );

4. В свойстве OnMouseMove компонента, на котором надо вызывать хинт, пишем:
Код

Hnt->SetCaption( "My Large Caption" );
Hnt->Show();

5. [ необязательно ] В свойстве OnMouseLeave этого же компонента пишем:
Код

Hnt->Hide();

Это теоретически необязательно, т.к. в классе метод AppMsg сам, по идее, должен регулировать отображение хинта через анализ типа курсора мыши (но это я не проверял).

Вот и все. Буду рад выслушать критику, комментарии и пожелания (только прошу не пинать слишком сильно, это всего второй более-менее объемный класс, который я написал).


--------------------
user posted image

user posted image
PM MAIL ICQ Skype   Вверх
pandrew
Дата 5.4.2007, 16:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 213
Регистрация: 27.3.2006

Репутация: 3
Всего: 3



Цитата(mr.Anderson @ 5.4.2007,  13:51)
Мне не нравилось то, что нельзя увеличить задержку Hint'а, нельзя настроить его стиль, который я написал).

А свойство TApplication::HintHidePause не помогало? Что касается стиля, есть хинт-классы сторонних производителей. Я использую TRzBalloonHints достаточно симпатичный компонент.
М.б. логичней было выводить свой класс из THintWindow, подменив отрисовку, раз уж так не нравилась. Или хотя бы посмотреть его исходники. И уж точно надо было выводить свой класс хотя бы от TComponent, дабы обеспечить корректность в рамках VCL.
PM MAIL   Вверх
mr.Anderson
Дата 5.4.2007, 16:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


iOS Lead Developer
****


Профиль
Группа: Участник Клуба
Сообщений: 3374
Регистрация: 20.12.2004
Где: далеко

Репутация: 3
Всего: 128



Цитата
есть хинт-классы сторонних производителей

Тут смысл не столько в заменителе (сторонние компоненты всегда можно найти), а в том, что написано своими руками. Практика.

Насчет наследования - я подумал, зачем выводить от TComponent, если все равно его свойства я не использую?

Добавлено @ 16:35
Кстати, а где этот компонент TRzBalloonHints можно скачать (для билдера), не подскажете?

Это сообщение отредактировал(а) mr.Anderson - 5.4.2007, 16:48


--------------------
user posted image

user posted image
PM MAIL ICQ Skype   Вверх
mr.Anderson
Дата 5.4.2007, 21:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


iOS Lead Developer
****


Профиль
Группа: Участник Клуба
Сообщений: 3374
Регистрация: 20.12.2004
Где: далеко

Репутация: 3
Всего: 128



Так. Вот доработанная версия (огромное спасибо Ctrl_alt_del за большую помощь в доработке).

Изменения:
[+] Метод AppMsg больше не используется (вместо него - хук на мышь), так что теперь можно при использовании данного класса определить собственный метод AppMsg.
[+] Загрузка процессора при перемещении хинта снижена до 20% (раньше было 40%).
[+] ЧАСТИЧНО работает задержка.

Задержка работает именно частично. Смысл: хинт через заданное время (метод SetDelay( int ) ) пропадает. Проблема в том, что он заново не появляется, когда требуется. Почему - я до сих пор теряюсь в догадках. Прошу всех, кто сможет, помочь.
Код

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

#ifndef VCL_H
#define VCL_H
#endif
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------

enum TAllowedFonts { afArial, afBookAntiqua, afBookmanOldStyle,
                     afComicSansMS, afCourier, afCourierNew,
                     afFixedsys, afGOSTtypeA, afImpact, afLucidaConsole,
                     afLucidaSansUnicode, afMonotypeCorsiva, afMSSansSerif,
                     afSystem, afTerminal, afTimesNewRoman };
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------

class TPanelHint {
 public:
  __fastcall TPanelHint( TPanel *, void * = IDC_HAND, unsigned short = 0 );
  __fastcall TPanelHint( TPanel *, TColor, TColor, TAllowedFonts, TFontStyles, void *, unsigned short );
  virtual __fastcall ~TPanelHint( void );

  void __fastcall Show( void );
  void __fastcall Hide( void );
  inline bool __fastcall GetVisibility( void )
   { return this->PSrc->Visible; }

  TPanelHint & __fastcall SetCaption( AnsiString );
  inline AnsiString __fastcall GetCaption( void )
   { return this->LSrcCaption->Caption; }

  TPanelHint & __fastcall SetBackColor( TColor );
  inline TColor __fastcall GetBackColor( void )
   { return this->PSrc->Color; }

  TPanelHint & __fastcall SetFontColor( TColor );
  inline TColor __fastcall GetFontColor( void )
   { return this->LSrcCaption->Font->Color; }

  TPanelHint & __fastcall SetFontName( TAllowedFonts );
  inline AnsiString __fastcall GetFontName( void )
   { return this->LSrcCaption->Font->Name; }
  inline TAllowedFonts __fastcall GetFontNameAF( void )
   { return this->Convert( this->LSrcCaption->Font->Name ); }

  TPanelHint & __fastcall SetFontStyle( TFontStyles );
  inline TFontStyles __fastcall GetFontStyle( void )
   { return this->LSrcCaption->Font->Style; }

  TPanelHint & __fastcall SetDelay( unsigned short );
  inline unsigned short __fastcall GetDelay( void )
   { return ( this->TMR->Interval/1000 ); }

  TPanelHint & __fastcall SetCursorIdentifier( void * );
  TPanelHint & __fastcall SetCursorPosition( int, int );
  TPanelHint & __fastcall SetCursorPosition( tagPOINT );
  inline TPoint __fastcall GetCursorPosition( void )
   { return this->curPos; }

  static LRESULT CALLBACK MouseProcessor( int nCode, WPARAM wParam, LPARAM lParam );

 private:
  TPanel *PSrc;
  TLabel *LSrcCaption;
  TTimer *TMR;
  void *curIdentifier;
  tagPOINT curPos;

  static HHOOK hHook;
  static HWND PHandle;
  static bool ShowFlag;

  AnsiString __fastcall Convert( TAllowedFonts );
  TAllowedFonts __fastcall Convert( AnsiString );

  void __fastcall CreateCaption( void );
  void __fastcall CreateTimer( void );
  void __fastcall SetHintPosition( void );
  void __fastcall CalculateCaptionPos( void );
  void __fastcall CalculateSize( void );

  void __fastcall OnTimer( TObject * );
};
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------

HHOOK TPanelHint::hHook = NULL;
HWND TPanelHint::PHandle = NULL;
bool TPanelHint::ShowFlag = true;

__fastcall TPanelHint::TPanelHint( TPanel *P, void *cursorIdentifier,
                                   unsigned short DelaySeconds )
{
 this->PSrc = P;
 this->PSrc->Caption = "";

 this->CreateCaption();

 this->CreateTimer();
 this->SetDelay( DelaySeconds * 1000 );

 this->curIdentifier = cursorIdentifier;

 hHook = NULL;
 PHandle = this->PSrc->Handle;
 SetWindowsHookEx( WH_MOUSE, (HOOKPROC)&MouseProcessor, NULL, 0 );
}
//---------------------------------------------------------------------------

__fastcall TPanelHint::TPanelHint( TPanel *P, TColor BackColor,
                                   TColor FontColor, TAllowedFonts FontName,
                                   TFontStyles FontStyle, void * cursorIdentifier,
                                   unsigned short DelaySeconds )
{
 this->PSrc = P;
 this->PSrc->Caption = "";
 this->PSrc->Color = BackColor;
 this->PSrc->Font->Color = FontColor;
 this->PSrc->Font->Name = this->Convert( FontName );
 this->PSrc->Font->Style = FontStyle;

 this->CreateCaption();

 this->curIdentifier = cursorIdentifier;

 this->CreateTimer();
 this->SetDelay( DelaySeconds * 1000 );

 hHook = NULL;
 PHandle = this->PSrc->Handle;
 SetWindowsHookEx( WH_MOUSE, (HOOKPROC)&MouseProcessor, NULL, 0 );
}
//---------------------------------------------------------------------------

__fastcall TPanelHint::~TPanelHint( void )
{
 delete this->PSrc;
 delete this->LSrcCaption;
 delete this->TMR;
 UnhookWindowsHookEx( hHook );
}
//---------------------------------------------------------------------------

void __fastcall TPanelHint::Show( void )
{
 if( this->GetCaption().IsEmpty() )
  return;

 if( TPanelHint::ShowFlag ) {
  GetCursorPos( &curPos );
  this->SetHintPosition();
  this->PSrc->Visible = true;
 }
 
 if( this->GetDelay() )
  this->TMR->Enabled = true;
}
//---------------------------------------------------------------------------

void __fastcall TPanelHint::Hide( void )
{
 this->PSrc->Visible = false;
}
//---------------------------------------------------------------------------

TPanelHint & __fastcall TPanelHint::SetCaption( AnsiString Caption )
{
 this->LSrcCaption->Caption = Caption;
 this->CalculateCaptionPos();

 return *this;
}
//---------------------------------------------------------------------------

TPanelHint & __fastcall TPanelHint::SetBackColor( TColor Color )
{
 this->PSrc->Color = Color;

 return *this;
}
//---------------------------------------------------------------------------

TPanelHint & __fastcall TPanelHint::SetFontColor( TColor Color )
{
 this->LSrcCaption->Font->Color = Color;

 return *this;
}
//---------------------------------------------------------------------------

TPanelHint & __fastcall TPanelHint::SetFontName( TAllowedFonts FontName )
{
 this->LSrcCaption->Font->Name = this->Convert( FontName );

 return *this;
}
//---------------------------------------------------------------------------

TPanelHint & __fastcall TPanelHint::SetFontStyle( TFontStyles FontStyle )
{
 this->LSrcCaption->Font->Style = FontStyle;

 return *this;
}
//---------------------------------------------------------------------------

TPanelHint & __fastcall TPanelHint::SetDelay( unsigned short Delay )
{
 this->TMR->Interval = Delay * 1000;

 return *this;
}
//---------------------------------------------------------------------------

TPanelHint & __fastcall TPanelHint::SetCursorIdentifier( void *Identifier )
{
 this->curIdentifier = Identifier;

 return *this;
}
//---------------------------------------------------------------------------

TPanelHint & __fastcall TPanelHint::SetCursorPosition( int X, int Y )
{
 this->curPos.x = X;
 this->curPos.y = Y;

 if( this->GetVisibility() )
  this->SetHintPosition();

 return *this;
}
//---------------------------------------------------------------------------

TPanelHint & __fastcall TPanelHint::SetCursorPosition( tagPOINT Position )
{
 this->curPos = Position;

 if( this->GetVisibility() )
  this->SetHintPosition();

 return *this;
}
//---------------------------------------------------------------------------

LRESULT CALLBACK TPanelHint::MouseProcessor( int nCode, WPARAM wParam, LPARAM lParam )
{
 if( wParam == WM_MOUSEMOVE )
 {
  MOUSEHOOKSTRUCT *pMouse = (MOUSEHOOKSTRUCT*)lParam;

  if( TPanelHint::PHandle == pMouse->hwnd )
  {
   if( TPanelHint::ShowFlag )
   {
    tagRECT rect;
    GetWindowRect( TPanelHint::PHandle, &rect );
    MoveWindow( TPanelHint::PHandle, pMouse->pt.x + 10, pMouse->pt.y + 15, ( rect.right - rect.left ), ( rect.bottom - rect.top ), TRUE );
    FindControl( TPanelHint::PHandle )->Parent->Repaint();
   }
  }
  else TPanelHint::ShowFlag = true; //включаем повторное отображение хинта
 }

 return CallNextHookEx( TPanelHint::hHook, nCode, wParam, lParam );
}
//---------------------------------------------------------------------------

AnsiString __fastcall TPanelHint::Convert( TAllowedFonts FontName )
{
 switch( FontName ) {
  case afArial: return "Arial";
  case afBookAntiqua: return "Book Antiqua";
  case afBookmanOldStyle: return "Bookman Old Style";
  case afCourier: return "Courier";
  case afCourierNew: return "Courier New";
  case afFixedsys: return "Fixedsys";
  case afGOSTtypeA: return "GOST type A";
  case afLucidaConsole: return "Lucida Console";
  case afLucidaSansUnicode: return "Lucida Sans Unicode";
  case afMonotypeCorsiva: return "Monotype Corsiva";
  case afMSSansSerif: return "MS Sans Serif";
  case afSystem: return "System";
  case afTerminal: return "Terminal";
  case afTimesNewRoman: return "Times New Roman";
  default: break;
 }

 return "";
}
//---------------------------------------------------------------------------

TAllowedFonts __fastcall TPanelHint::Convert( AnsiString FontName )
{
 if( FontName == "Arial" ) return afArial;
 if( FontName == "Book Antiqua" ) return afBookAntiqua;
 if( FontName == "Bookman Old Style" ) return afBookmanOldStyle;
 if( FontName == "Courier" ) return afCourier;
 if( FontName == "Courier New" ) return afCourierNew;
 if( FontName == "Fixedsys" ) return afFixedsys;
 if( FontName == "GOST type A" ) return afGOSTtypeA;
 if( FontName == "Lucida Console" ) return afLucidaConsole;
 if( FontName == "Lucida Sans Unicode" ) return afLucidaSansUnicode;
 if( FontName == "Monotype Corsiva" ) return afMonotypeCorsiva;
 if( FontName == "MS Sans Serif" ) return afMSSansSerif;
 if( FontName == "System" ) return afSystem;
 if( FontName == "Terminal" ) return afTerminal;
 if( FontName == "Times New Roman" ) return afTimesNewRoman;

 return afArial; //избегаем билдеровского предупреждения
}
//---------------------------------------------------------------------------

void __fastcall TPanelHint::CreateCaption( void )
{
 this->LSrcCaption = new TLabel( this->PSrc );
 this->LSrcCaption->Parent = this->PSrc;
 this->LSrcCaption->Transparent = true;
}
//---------------------------------------------------------------------------

void __fastcall TPanelHint::CreateTimer( void )
{
 this->TMR = new TTimer( this->PSrc );
 this->TMR->Enabled = false;
 this->TMR->OnTimer = this->OnTimer;
}
//---------------------------------------------------------------------------

void __fastcall TPanelHint::SetHintPosition( void )
{
 this->PSrc->Left = this->curPos.x + 10;
 this->PSrc->Top = this->curPos.y + 15;
}
//---------------------------------------------------------------------------

void __fastcall TPanelHint::CalculateCaptionPos( void )
{
 this->CalculateSize();

 this->LSrcCaption->Left = this->PSrc->Width / 2 - this->LSrcCaption->Width / 2;
 this->LSrcCaption->Top = this->PSrc->Height / 2 - this->LSrcCaption->Height / 2;
}
//---------------------------------------------------------------------------

void __fastcall TPanelHint::CalculateSize( void )
{
 this->PSrc->Width = this->LSrcCaption->Width + 30;
 this->PSrc->Height = this->LSrcCaption->Height + 10; 
}
//---------------------------------------------------------------------------

void __fastcall TPanelHint::OnTimer( TObject *Sender )
{
 this->Hide();
 this->ShowFlag = false;
 this->TMR->Enabled = false;
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------



--------------------
user posted image

user posted image
PM MAIL ICQ Skype   Вверх
pandrew
Дата 6.4.2007, 08:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 213
Регистрация: 27.3.2006

Репутация: 3
Всего: 3



Цитата(mr.Anderson @ 5.4.2007,  16:31)
Кстати, а где этот компонент TRzBalloonHints можно скачать (для билдера), не подскажете?

Это часть пакета Raize Components v 3.06.
PM MAIL   Вверх
Vyacheslav
Дата 6.4.2007, 10:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Цитата(mr.Anderson @  5.4.2007,  16:31 Найти цитируемый пост)
Насчет наследования - я подумал, зачем выводить от TComponent, если все равно его свойства я не использую?


Вопрос в том, что не используете, потому что не знаете как использовать, а не потому что нет необходимости.  А тут хотя бы могли ввести проверти. Это первое.
Второе. Стиль кодирования выдает сразу Вас как начинающего smile Это не сипласпласный стиль. Третье. Почему Вы ограничили набор шрифтов и зачем было вводить для этого enum. Боитесь, что name будет набираться не првильно? Но если я мне нужен жесткий шрифт я его в коде уж точно наберу правильно. А если он будет меняться в процессе работы программы, то всегда можно воспользоватться именами отсюда TScreen::Fonts
Четвертое. Ну и зачем Вы во всех сетах возращаете ссылку на this? Необходимости в этом абсолютно никакой. Разве что демонстраций собственных познаний.



--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
mr.Anderson
Дата 6.4.2007, 13:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


iOS Lead Developer
****


Профиль
Группа: Участник Клуба
Сообщений: 3374
Регистрация: 20.12.2004
Где: далеко

Репутация: 3
Всего: 128



Цитата
Стиль кодирования выдает сразу Вас как начинающего

Я даже и спорить не стану. smile Но вы бы хотя бы сказали, что именно говорит о том, что я начинающий.
Цитата
Боитесь, что name будет набираться не првильно

Вот именно поэтому. Но если есть методы, чтобы этого избежать, то я могу убрать это. Хотя, определение собственных перечисляемых типов мне что-то последнее время нравится. smile
Цитата
Ну и зачем Вы во всех сетах возращаете ссылку на this

А как же? А если я не буду возвращать, разве можно будет каскадировать вызовы функций? Если можно, то я немедленно уберу возврат, я просто не знал, что можно и без него обойтись...


--------------------
user posted image

user posted image
PM MAIL ICQ Skype   Вверх
Vyacheslav
Дата 6.4.2007, 14:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Цитата(mr.Anderson @  6.4.2007,  13:17 Найти цитируемый пост)
Я даже и спорить не стану.  Но вы бы хотя бы сказали, что именно говорит о том, что я начинающий.

Ну хотя бы использование постоянное this внутри методов. Насколько я знаю, это так пишут джависты

Цитата(mr.Anderson @  6.4.2007,  13:17 Найти цитируемый пост)
А как же? А если я не буду возвращать, разве можно будет каскадировать вызовы функций? Если можно, то я немедленно уберу возврат, я просто не знал, что можно и без него обойтись... 

Ага. То есть Вы в принципе в отличие от остальных не допускаете метод, возвращающий void. Иначе как каскадировать? 
Типа  этого?
Код

Hnt->SetBackColor( clBlack ).SetFontColor( clWhite );

Вы считаете, что это удобно и наглядно?  
Не говоря уже о том, что сеттер обычно возвращает  void. Конечно, можно все делать не так как все. Но стоит ли? Это как придумать свой собственный язык. Говорить то на нем, конечно можно. Только с кем? 


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
HappyLife
Дата 6.4.2007, 14:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 642
Регистрация: 17.5.2006

Репутация: 4
Всего: 8



Vyacheslav, Возвращать this, очень неплохой прием для создания гусениц.... Типо таких)
Код

MySuperMegaObject.SetPriceForMySuperObject("10000$").SetYourStatus("Looser").SetMyStatus("haker");

 smile  smile  smile 
PM MAIL   Вверх
mr.Anderson
Дата 6.4.2007, 17:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


iOS Lead Developer
****


Профиль
Группа: Участник Клуба
Сообщений: 3374
Регистрация: 20.12.2004
Где: далеко

Репутация: 3
Всего: 128



Vyacheslav, никогда бы не подумал, что допускать каскадирование в классе - признак дурного тона... Ну, если так, то ладно, можно и убрать. Хотя, я бы оставил. Почему? Не нравится - не пользуйтесь, а вдруг кому захочется?

Насчет this-ов повсюду - почему же это признак начинающего программиста? Я, например, считаю, что с ними просто понятней и наглядней. Понятно, что за переменную используем - класса или определенную внутри функции. Это дело привычки, имхо. И уж точно не признак того, что я "джавист" - на Java не писал никогда. smile Лучше назовите более существенные признаки начинающего программиста.


--------------------
user posted image

user posted image
PM MAIL ICQ Skype   Вверх
codelord
Дата 6.4.2007, 20:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 777
Регистрация: 7.5.2005
Где: ты моя темноглаза я где?!

Репутация: 16
Всего: 39



Цитата(mr.Anderson @  6.4.2007,  13:02 Найти цитируемый пост)
Лучше назовите более существенные признаки начинающего программиста.

я бы на твоем месте особо не спорил,  поверь примеры можно найти.

пс. себя я тоже считаю начинающим.



--------------------
Доступен поиск по исходным кодам в GOOGLE.
http://www.google.com/codesearch
PM MAIL   Вверх
mr.Anderson
Дата 6.4.2007, 20:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


iOS Lead Developer
****


Профиль
Группа: Участник Клуба
Сообщений: 3374
Регистрация: 20.12.2004
Где: далеко

Репутация: 3
Всего: 128



codelord, да я не спорю. smile Я просто хочу понять, почему видно, что я начинающий. Я тоже считаю себя начинающим, просто хотелось бы знать опознавательные признаки этого явления. smile


--------------------
user posted image

user posted image
PM MAIL ICQ Skype   Вверх
Vyacheslav
Дата 9.4.2007, 10:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Цитата(mr.Anderson @  6.4.2007,  17:02 Найти цитируемый пост)
Лучше назовите более существенные признаки начинающего программиста. 

smile Они достаточно существенны, что бы любой из опытных программистов определи в Вас новичка.  Об идее тут уже сказали без меня и правильно.
1.Для изменения стиля следовало просто отнаследоваться от THintWindow, тем более он для этого предназначен
Цитата

Override THintWindow to customize the window that appears automatically for controls with their ShowHint property set to true. After overriding THintWindow to create a new derived type, assign the new type to the global HintWindowClass variable at application startup, so that the new hint window type is used for Help Hints

Причем от Вас, как от программиста требуется всего лишь отнаследовать новый класс и его тип присвоить глобальной переменной HintWindowClass. И все. 


Цитата(mr.Anderson @  6.4.2007,  20:59 Найти цитируемый пост)
Я просто хочу понять, почему видно, что я начинающий. Я тоже считаю себя начинающим, просто хотелось бы знать опознавательные признаки этого явления. 

Я Вам назвал. Просто ощущение субъективно, но для меня очевидно. Вплоть до подхода
Цитата(mr.Anderson @  6.4.2007,  17:02 Найти цитируемый пост)
а вдруг кому захочется?

Делать фичи на всякий случай , "вдруг кому захочется" - это кстати один из таких признаков.
Все очень просто: возьмите код любой из открытых библиотек. Есть такое понятие - стиль кодирование. Посмотрите, как пишут профессионалы и копируйте. Кстати виртуальный деструктор во втором варианте из той же оперы?  "Вдруг кому захочется" отнаследоваться и воспользоваться принципом полиморфизма? И это с учетом того, что виртуальных функций я не вижу( может просмотрел)



--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
mr.Anderson
Дата 9.4.2007, 17:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


iOS Lead Developer
****


Профиль
Группа: Участник Клуба
Сообщений: 3374
Регистрация: 20.12.2004
Где: далеко

Репутация: 3
Всего: 128



Насчет виртуальных методов - я его сделал виртуальным, т.к. раньше там был виртуальный переопределенный метод AppMsg. 

Насчет возврата this-ов - их рекомендуется возвращать для реализации возможности каскадирования по учебнику Дейтелов. Я ж должен следовать какому-то пособию.

Вот более новый код:
Код

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

#ifndef VCL_H
#include <vcl.h>
#endif
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------

class TPanelHint {
 public:
  __fastcall TPanelHint( TPanel * );
  __fastcall TPanelHint( TPanel *, TColor, TColor, AnsiString, TFontStyles );
  __fastcall ~TPanelHint( void );

  void __fastcall Show( void );
  void __fastcall Hide( void );
  inline bool __fastcall GetVisibility( void )
   { return this->PSrc->Visible; }

  TPanelHint & __fastcall SetCaption( AnsiString );
  inline AnsiString __fastcall GetCaption( void )
   { return this->LSrcCaption->Caption; }

  TPanelHint & __fastcall SetBackColor( TColor );
  inline TColor __fastcall GetBackColor( void )
   { return this->PSrc->Color; }

  TPanelHint & __fastcall SetFontColor( TColor );
  inline TColor __fastcall GetFontColor( void )
   { return this->LSrcCaption->Font->Color; }

  TPanelHint & __fastcall SetFontName( AnsiString );
  inline AnsiString __fastcall GetFontName( void )
   { return this->LSrcCaption->Font->Name; }

  TPanelHint & __fastcall SetFontStyle( TFontStyles );
  inline TFontStyles __fastcall GetFontStyle( void )
   { return this->LSrcCaption->Font->Style; }

  TPanelHint & __fastcall SetCursorPosition( int, int );
  TPanelHint & __fastcall SetCursorPosition( tagPOINT );
  inline TPoint __fastcall GetCursorPosition( void )
   { return this->curPos; }

  static LRESULT CALLBACK MouseProcessor( int nCode, WPARAM wParam, LPARAM lParam );

 private:
  TPanel *PSrc;
  TLabel *LSrcCaption;
  tagPOINT curPos;

  static HHOOK hHook;
  static HWND HintHandle;

  void __fastcall CreateCaption( void );
  void __fastcall SetHintPosition( void );
  void __fastcall CalculateCaptionPos( void );
  void __fastcall CalculateSize( void );
};
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------

HHOOK TPanelHint::hHook = NULL;
HWND TPanelHint::HintHandle = NULL;

__fastcall TPanelHint::TPanelHint( TPanel *P )
{
 if( P == NULL ) return;

 TPanelHint::HintHandle = P->Handle;
 this->PSrc = P;
 this->PSrc->Caption = "";

 this->CreateCaption();

 SetWindowsHookEx( WH_MOUSE, (HOOKPROC)&TPanelHint::MouseProcessor, NULL, 0 );
}
//---------------------------------------------------------------------------

__fastcall TPanelHint::TPanelHint( TPanel *P, TColor BackColor,
                                   TColor FontColor, AnsiString FontName,
                                   TFontStyles FontStyle )
{
 if( P == NULL || FontName == "" ) return;
 
 TPanelHint::HintHandle = P->Handle;
 this->PSrc = P;
 this->PSrc->Caption = "";
 this->PSrc->Color = BackColor;
 this->PSrc->Font->Color = FontColor;
 this->PSrc->Font->Name = FontName;
 this->PSrc->Font->Style = FontStyle;

 this->CreateCaption();

 SetWindowsHookEx( WH_MOUSE, (HOOKPROC)&TPanelHint::MouseProcessor, NULL, 0 );
}
//---------------------------------------------------------------------------

__fastcall TPanelHint::~TPanelHint( void )
{
 if( this->PSrc )
  delete this->PSrc;

 if( this->LSrcCaption )
  delete this->LSrcCaption;

 UnhookWindowsHookEx( TPanelHint::hHook );
}
//---------------------------------------------------------------------------

void __fastcall TPanelHint::Show( void )
{
 if( this->GetCaption().IsEmpty() )
  return;

 GetCursorPos( &(this->curPos) );
 this->SetHintPosition();
 this->PSrc->BringToFront();
 this->PSrc->Visible = true;
}
//---------------------------------------------------------------------------

void __fastcall TPanelHint::Hide( void )
{
 this->PSrc->Visible = false;
}
//---------------------------------------------------------------------------

TPanelHint & __fastcall TPanelHint::SetCaption( AnsiString Caption )
{
 this->LSrcCaption->Caption = Caption;
 this->CalculateCaptionPos();

 return *this;
}
//---------------------------------------------------------------------------

TPanelHint & __fastcall TPanelHint::SetBackColor( TColor Color )
{
 this->PSrc->Color = Color;

 return *this;
}
//---------------------------------------------------------------------------

TPanelHint & __fastcall TPanelHint::SetFontColor( TColor Color )
{
 this->LSrcCaption->Font->Color = Color;

 return *this;
}
//---------------------------------------------------------------------------

TPanelHint & __fastcall TPanelHint::SetFontName( AnsiString FontName )
{
 this->LSrcCaption->Font->Name = FontName;

 return *this;
}
//---------------------------------------------------------------------------

TPanelHint & __fastcall TPanelHint::SetFontStyle( TFontStyles FontStyle )
{
 this->LSrcCaption->Font->Style = FontStyle;

 return *this;
}
//---------------------------------------------------------------------------

TPanelHint & __fastcall TPanelHint::SetCursorPosition( int X, int Y )
{
 this->curPos.x = X;
 this->curPos.y = Y;

 if( this->GetVisibility() )
  this->SetHintPosition();

 return *this;
}
//---------------------------------------------------------------------------

TPanelHint & __fastcall TPanelHint::SetCursorPosition( tagPOINT Position )
{
 this->curPos = Position;

 if( this->GetVisibility() )
  this->SetHintPosition();

 return *this;
}
//---------------------------------------------------------------------------

LRESULT CALLBACK TPanelHint::MouseProcessor( int nCode, WPARAM wParam, LPARAM lParam )
{
 if( wParam == WM_MOUSEMOVE )
 {
  MOUSEHOOKSTRUCT *pMouse = (MOUSEHOOKSTRUCT*)lParam;

  tagRECT rect;
  GetWindowRect( TPanelHint::HintHandle, &rect );
  MoveWindow( TPanelHint::HintHandle, pMouse->pt.x + 10, pMouse->pt.y + 15, ( rect.right - rect.left ), ( rect.bottom - rect.top ), TRUE );
 }

 return CallNextHookEx( TPanelHint::hHook, nCode, wParam, lParam );
}
//---------------------------------------------------------------------------

void __fastcall TPanelHint::CreateCaption( void )
{
 this->LSrcCaption = new TLabel( this->PSrc );
 this->LSrcCaption->Parent = this->PSrc;
 this->LSrcCaption->Transparent = true;
}
//---------------------------------------------------------------------------

void __fastcall TPanelHint::SetHintPosition( void )
{
 this->PSrc->Left = this->curPos.x + 10;
 this->PSrc->Top = this->curPos.y + 15;
}
//---------------------------------------------------------------------------

void __fastcall TPanelHint::CalculateCaptionPos( void )
{
 this->CalculateSize();

 this->LSrcCaption->Left = this->PSrc->Width / 2 - this->LSrcCaption->Width / 2;
 this->LSrcCaption->Top = this->PSrc->Height / 2 - this->LSrcCaption->Height / 2;
}
//---------------------------------------------------------------------------

void __fastcall TPanelHint::CalculateSize( void )
{
 this->PSrc->Width = this->LSrcCaption->Width + 30;
 this->PSrc->Height = this->LSrcCaption->Height + 10;
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------



--------------------
user posted image

user posted image
PM MAIL ICQ Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0653 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.