Анимация кнопок
1. Нормальная
2. Посвеченная
3. Нажатая
с 1. и 3. У меня проблем не возникает тут все просто, меняешь изображение на OnMouseDown и OnMouseUp.
А вот как сделать так что бы при наведении мышкой менялось изображение на Подсвеченное, а при выходе указателя за пределы кнопки обратно менялось на Нормальное.
Я использую для изображения TImage.
для изменения размеров шрифта в TLable, я делал так a как сделать для TImage:
void __fastcall TForm1::IDS_EXITMouseMove(TObject *Sender,
TShiftState Shift, int X, int Y)
{
TStaticText * pText = static_cast<TStaticText*>(Sender);
SetCapture(pText->Handle);
if ( (X > Left)&&( X < (Left+pText->Width))&&
( Y > Top)&& (Y < (Top+pText->Height))) pText->Font->Size = HIGHTEXT;
else {
pText->Font->Size = LOWTEXT;
ReleaseCapture();
}
}
там все работало, но для TImage я не могу сделать SetCapture, поскольку там нет указателя на Handle.
Я использую для изображения TImage.
для изменения размеров шрифта в TLable, я делал так a как сделать для TImage:
....
там все работало, но для TImage я не могу сделать SetCapture, поскольку там нет указателя на Handle.
А это что?
А это что?
Это не тот Handle.
Для SetCapture требуется HWND, а не HDC.
"Управляющему Ада" могу посоветовать использовать Handle кнопки, на которой лежит Image (если, конечно, эта кнопка - оконный элемент, имеющий HWND). Или обойтись без SetCapture. Или без TImage.
А ещё проще - найти уже готовый компонент такой кнопки. Наверняка его уже сделали. :)
А ещё проще - найти уже готовый компонент такой кнопки. Наверняка его уже сделали. :)
Обычная кнопка панели инструментов - TToolButton обладает всеми необходимыми свойствами. Надо только внимательно прочитать в MSDN, как правильно создавать изображения для каждого состояния кнопки. Кажется, там надо было заморачиваться с масками...
Кстати, есть примеры, когда программисты Майкрософт использовали Toolbar с одной кнопкой, чтобы не заморачиваться написанием отдельного компонента.
Такая проблема, необходимо анимировать кнопку в 3х состояниях:
1. Нормальная
2. Посвеченная
3. Нажатая
с 1. и 3. У меня проблем не возникает тут все просто, меняешь изображение на OnMouseDown и OnMouseUp.
А вот как сделать так что бы при наведении мышкой менялось изображение на Подсвеченное, а при выходе указателя за пределы кнопки обратно менялось на Нормальное.
Я использую для изображения TImage.
для изменения размеров шрифта в TLable, я делал так a как сделать для TImage:
void __fastcall TForm1::IDS_EXITMouseMove(TObject *Sender,
TShiftState Shift, int X, int Y)
{
TStaticText * pText = static_cast<TStaticText*>(Sender);
SetCapture(pText->Handle);
if ( (X > Left)&&( X < (Left+pText->Width))&&
( Y > Top)&& (Y < (Top+pText->Height))) pText->Font->Size = HIGHTEXT;
else {
pText->Font->Size = LOWTEXT;
ReleaseCapture();
}
}
там все работало, но для TImage я не могу сделать SetCapture, поскольку там нет указателя на Handle.
не так давно я загорелся идеей сделать свой набор Flat компонентов - Button, Edit, Memo, ComboBox, PageControl (ну не нравятся мне объемные!) - кое-что уже сделал и в своих прогах использую токо свои компоненты, параллельно их дорабатывая (все-таки еще сыроваты :() и расширяя набор... так вот, мне тоже понравилась идея когда в момент наведения мышой на кнопку она меняет цвет на то время пока мыша находится над ней. долго я искал решение и потом нашел тоже в наборе самодельных компонент и применил в своем. идея заключается в том, что в обработчике события OnMove меняется цвет кнопки и создается таймер, по тикам которого проверяется положение мыши... как только при очередном тике окажется что координаты мыши вне кнопки цвет меняется обратно и таймер прибивается (чтобы зря память не занимал).
не так давно я загорелся идеей сделать свой набор Flat компонентов - Button, Edit, Memo, ComboBox, PageControl (ну не нравятся мне объемные!) - кое-что уже сделал и в своих прогах использую токо свои компоненты, параллельно их дорабатывая (все-таки еще сыроваты :() и расширяя набор... так вот, мне тоже понравилась идея когда в момент наведения мышой на кнопку она меняет цвет на то время пока мыша находится над ней. долго я искал решение и потом нашел тоже в наборе самодельных компонент и применил в своем. идея заключается в том, что в обработчике события OnMove меняется цвет кнопки и создается таймер, по тикам которого проверяется положение мыши... как только при очередном тике окажется что координаты мыши вне кнопки цвет меняется обратно и таймер прибивается (чтобы зря память не занимал).
Таймер напрямую жрет ресурсы процесора, лучше не так живи проще, кинь Image и на него свою кнопку кнопку и обрабатывай MouseMove я так всегда делаю и поверь это лучше чем таймер....
Есть варианты по сложнее смотри:
ты можешь обрабатывать все сообщения винды, то есть если тебе нуно что-то подсветить ты просто при наведении, какой нить объект ставишь в сигнальное состояние, потом юзверь мышкой или клавой дергает сообщения льются ты смотришь координаты мыши и если они не там то подсветку убираешь.
и еще вариент см:
Моно отлавливать потерю фокуса, но тоже только через карту сообщений....
Воть думаю пригодится...
Relax ты случаем не с примы?
...
А вот как сделать так что бы при наведении мышкой менялось изображение на Подсвеченное, а при выходе указателя за пределы кнопки обратно менялось на Нормальное
...
Это просто и ненадо мудрить с таймерами и тулбарами...
Для производных от TControl eсть два волшебных события CM_MOUSEENTER и CM_MOUSELEAVE.
//hpp
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *Button1;
TPanel *Panel1;
TLabel *Label1;
void __fastcall Panel1MouseMove(TObject *Sender, TShiftState Shift,
int X, int Y);
void __fastcall FormMouseMove(TObject *Sender, TShiftState Shift,
int X, int Y);
private: // User declarations
bool inLabel;
TWndMethod OldWndProc;
void __fastcall NewWndProc(TMessage &Msg);
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
//cpp
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
//SubClassing...
OldWndProc = Button1->WindowProc;
Button1->WindowProc = NewWndProc;
inLabel = false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::NewWndProc(TMessage &Msg)
{
switch (Msg.Msg)
{
case CM_MOUSEENTER:
{
//это для примера, рисуйте Сами...
Button1->Caption = "CM_MOUSEENTER";
break;
}
case CM_MOUSELEAVE:
{
Button1->Caption = "CM_MOUSELEAVE";
break;
}
case WM_DESTROY:
{
Button1->WindowProc = OldWndProc;
break;
}
}
OldWndProc(Msg);
}
/*Далее еще один вариант:
бросаешь на форму панель, на панель контрол, делаешь его на 1-2 пикселя меньше и ... далее и так все ясно. Ниже имитируется наведение на адрес в инете*/
void __fastcall TForm1::Panel1MouseMove(TObject *Sender, TShiftState Shift,
int X, int Y)
{
if(!inLabel) {
inLabel = true;
Label1->Font->Color = clBlue;
Label1->Font->Style = TFontStyles() << fsUnderline;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift,
int X, int Y)
{
if(inLabel) {
inLabel = false;
Label1->Font->Color = clBlack;
Label1->Font->Style = TFontStyles();
}
}
Таймер напрямую жрет ресурсы процесора, лучше не так живи проще, кинь Image и на него свою кнопку кнопку и обрабатывай MouseMove я так всегда делаю и поверь это лучше чем таймер....
Есть варианты по сложнее смотри:
ты можешь обрабатывать все сообщения винды, то есть если тебе нуно что-то подсветить ты просто при наведении, какой нить объект ставишь в сигнальное состояние, потом юзверь мышкой или клавой дергает сообщения льются ты смотришь координаты мыши и если они не там то подсветку убираешь.
и еще вариент см:
Моно отлавливать потерю фокуса, но тоже только через карту сообщений....
Воть думаю пригодится...
Relax ты случаем не с примы?
вариант с таймером мне самому не нравится - просто эт было самое простое решение - насчет сообщений винды - попробую... хотя, честно говоря, то что таймер жрет проц во время наведения мыши на кнопку меня не сильно напрягает - это же доли секунды... да и велика ли нагрузка?
я - с примы... :) ты, видимо, тоже?
вариант с таймером мне самому не нравится - просто эт было самое простое решение - насчет сообщений винды - попробую... хотя, честно говоря, то что таймер жрет проц во время наведения мыши на кнопку меня не сильно напрягает - это же доли секунды... да и велика ли нагрузка?
я - с примы... :) ты, видимо, тоже?
Нет я с кафедры информатики, но про тебя где-то слышал, но не помню где....
вопрос, а зачем обрабатывать CM_DESTROY?
Ты переназначаешь обработчики событий - потому обязательно должен вернуть все, ты ведь не можешь гарантировать, что в старой процедуре не создавалось ничего, что требует удаления. Фактически ты говоришь, что свою работу ты закончил - дальше - разбирайтесь сами. Мавр сделал свое дело - мавр может уходить...:)
Ты переназначаешь обработчики событий - потому обязательно должен вернуть все, ты ведь не можешь гарантировать, что в старой процедуре не создавалось ничего, что требует удаления.
Так и будет вызыватся та процедура, с сообщением WM_DESTROY, просто новая процедура делает дополнительные действия перед вызовом старой процедуры, да и то только в случае CM_MOUSEENTER, CM_MOUSELEAVE, а в остальном действуе таже самая процедура, или я чего-то не так понимаю?
В принципе не трудно дописать эти пару строчек кода, просто хочется разобратся.