Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Курсор над формой


Автор: Superklug 23.2.2009, 18:05
Доброго времени суток!
Окно моей программы должно быть полупрозрачным в случае если оно неактивно. Если сделать его активным или навести курсор мыши оно должно становиться непрозрачным...

Сначала пробовал обрабатывать сообщения CM_MOUSELEAVE и CM_MOUSEENTER, но они работают не корректно (если быстро перемещать курсор, то сообщения не возникают). Решил сделать проверку по таймеру.

Возник вопрос... Как определить находится ли курсор над моей формой?

Я сделал так: 
Код

if((Mouse->CursorPos.x>fmMain->Left)&&
   (Mouse->CursorPos.x<fmMain->Left+fmMain->Width)&&
   (Mouse->CursorPos.y>fmMain->Top)&&
   (Mouse->CursorPos.y<fmMain->Top+fmMain->Height))

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

Автор: THandle 23.2.2009, 18:20
Superklug, хммм... возможно что-то недопонял, но стандартные события формы OnMouseEnter, OnMouseLeave, OnMouseMove не подходят?

Автор: Dem_max 23.2.2009, 18:27
Так
Код

int Height, Width;
int Transparency = 60;
long ExtStyle;
TPoint cPt;
bool flMouseEnter = false;
bool flMouseLeave = true;
bool flSmall = true;

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

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
GetCursorPos(&cPt);
if(flSmall)
{
   if(int(cPt.y)<(Form1->Top+60)&&int(cPt.y)>Form1->Top&&int(cPt.x)>Form1->Left&&int(cPt.x)<(Form1->Left+120)&&flMouseEnter == false)
   {
      ExtStyle = GetWindowLong(Handle, GWL_EXSTYLE);
      SetWindowLong(Handle, GWL_EXSTYLE, ExtStyle | WS_EX_LAYERED);
      SetLayeredWindowAttributes(Handle,0,(255*100)/100,LWA_ALPHA);
      Form1->ClientHeight = 60;
      flMouseEnter = true;
      flMouseLeave = false;
   }
   if(int(cPt.y)<Form1->Top||int(cPt.y)>(Form1->Top+60)||int(cPt.x)>(Form1->Left+120)||int(cPt.x)<Form1->Left&&flMouseLeave == false)
   {
      ExtStyle = GetWindowLong(Handle, GWL_EXSTYLE);
      SetWindowLong(Handle, GWL_EXSTYLE, ExtStyle | WS_EX_LAYERED);
      SetLayeredWindowAttributes(Handle,0,(255*Transparency)/100,LWA_ALPHA);
      Form1->ClientHeight = 18;
      flMouseEnter = false;
      flMouseLeave = true;
   }
}
}
//---------------------------------------------------------------------------


результат

Автор: Superklug 23.2.2009, 18:38
THandle, Я пишу на Builder 6. Там нет таких событий... Переходить сейчас на другие версии уже поздно...


Dem_max, Проблема не устранена. Попробуйте сделать свою форму не поверх всех окон, потом перекройте часть формы другим окном и наведите курсор на перекрытый участок. Форма станет непрозрачной.

Автор: Mpak 23.2.2009, 23:56
Попробуйте добавить к способу Dem_max проверку на то, какое окно активно в момент наведения курсора на перекрытый участок smile

Автор: Dem_max 24.2.2009, 16:41
Вот держи код
Код

int Height, Width;
int Transparency = 60;
long ExtStyle;
TPoint cPt;
bool flMouseEnter = false;
bool flMouseLeave = true;
bool flSmall = true;

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

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
GetCursorPos(&cPt);
if(flSmall)
{
   if(int(cPt.y)<(Form1->Top+60)&&int(cPt.y)>Form1->Top&&int(cPt.x)>Form1->Left&&int(cPt.x)<(Form1->Left+120)&&flMouseEnter == false&&Application->Active)
   {
      ExtStyle = GetWindowLong(Handle, GWL_EXSTYLE);
      SetWindowLong(Handle, GWL_EXSTYLE, ExtStyle | WS_EX_LAYERED);
      SetLayeredWindowAttributes(Handle,0,(255*100)/100,LWA_ALPHA);
      Form1->ClientHeight = 60;
      flMouseEnter = true;
      flMouseLeave = false;
   }
   if(int(cPt.y)<Form1->Top||int(cPt.y)>(Form1->Top+60)||int(cPt.x)>(Form1->Left+120)||int(cPt.x)<Form1->Left&&flMouseLeave == false)
   {
      ExtStyle = GetWindowLong(Handle, GWL_EXSTYLE);
      SetWindowLong(Handle, GWL_EXSTYLE, ExtStyle | WS_EX_LAYERED);
      SetLayeredWindowAttributes(Handle,0,(255*Transparency)/100,LWA_ALPHA);
      Form1->ClientHeight = 18;
      flMouseEnter = false;
      flMouseLeave = true;
   }
}
}
//---------------------------------------------------------------------------

найди 1 отличие

Автор: Mpak 24.2.2009, 20:02
 smile 
А приз будет тому кто найдет?  smile 

Автор: Superklug 25.2.2009, 18:14
Эх( Опять меня не поняли...
Моя форма совсем не обязательно должна быть активна.

Попробую переформулировать... Необходимо узнать видна ли в данный момент под курсором моя форма. Т.е. необходимо учитывать не просто координаты, но и непосредственную видимость.

Автор: Dem_max 25.2.2009, 18:39
Superklug
непонятный ты какой то.
Лови WM_KILLFOCUS еще чтонибудь тогда

Автор: Superklug 25.2.2009, 18:40
Ну вроде работает) 
Код

if(WindowFromPoint(Mouse->CursorPos)==Form1->Handle)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)