Форум: "Основная";
Текущий архив: 2010.02.21;
Скачать: [xml.tar.bz2];
ВнизКак сделать мерцающий текст ? Найти похожие ветки
← →
KSergey © (2009-01-13 09:12) [40]> oxffff © (13.01.09 08:56) [38]
> через статический или динамический паттерн Visitor.
Да, да
Как раз о его реализации стандартными средствами дельфи в основном и речь.
← →
oxffff © (2009-01-13 10:01) [41]
> KSergey © (13.01.09 09:10) [39]
Есть еще идея. Суть:
Делаем перехват API функций например DrawTextA, в моргающий момент подставляем пустышку, которая делает просто:
add esp,ParamsCleanUpSize
ret
В момент отрисовки подставляем родную реализацию.
от обработки WM_ERASEBKGND отказываемся.
В итоге код мой меняется на
a.Msg:=WM_PAINT;
case state of
0:
begin
NativeHandler(Tmessage(A));
end;
1: begin
PatchApi
NativeHandler(Tmessage(A));
RestoreApi
end;
← →
{RASkov} © (2009-01-13 11:56) [42]А чем Visible:=not Visible; не подходит? Если контролы "неалигнутые"...
......если "алигнутые" то это понятно :)
← →
MsGuns © (2009-01-13 12:33) [43]>KSergey © (13.01.09 09:10) [39]
>Вообще штука вот в чем: вы говорите о том, как сделать собственно моргание. Я (и многое другие) - как удобно уравлять морганием нескольких контролов на одном общем механизме, в ОДНОМ месте с учетом того, что моргающие контролы вообще-то иногда дестроятся и это должно коректно обрабатываться, а не создавая объекты моргания на каждый визуальный контрол. И автору ка краз интерсне было как это одно место организовать, если посмотреть вопрос.
Ты верно уловил суть задачи :)
При этом "моргающие" ("бегущие") контролы могут принадлежать к разным формам, которые, кстати, могут еще и перекрывать друг друга. Вот почему нельзя привязываться к конкретным классам
← →
KSergey © (2009-01-13 13:14) [44]> MsGuns © (13.01.09 12:33) [43]
> Ты верно уловил суть задачи :)
Так оно ж явно написано.
> При этом "моргающие" ("бегущие") контролы могут принадлежать
> к разным формам, которые, кстати, могут еще и перекрывать
> друг друга. Вот почему нельзя привязываться к конкретным классам
Это не мешает.
Достаточно вынести "диспетчер моргания" в отдельный юнит, создавая единственный экземпляр "менеджера морганий" в initialization.
А без класса все равно нам не обойтись: все обработчики событий"того же таймера) - только методами могут быть. Так что максимум что можно - это обернуть объект и обращение к нему в некую функцию, но по сути это не избавит нас от объектов, так что смысла упираться особого не вижу.
← →
KSergey © (2009-01-13 13:16) [45]Желание oxffff сделать еще и процессморгания супер универсальным - как бы хорошее с виду, но нереализуемое ввиду кучи нюансов, спасибо, я уже наступал на похожие грабли в желании "сейчас быстренько все сообщения перехватим и как надо обработаем". Слишком много нюансов выползает, ну нафик
← →
oxffff © (2009-01-13 21:43) [46]
> KSergey © (13.01.09 13:16) [45]
> Желание oxffff сделать еще и процессморгания супер универсальным
> - как бы хорошее с виду, но нереализуемое ввиду кучи нюансов,
> спасибо, я уже наступал на похожие грабли в желании "сейчас
> быстренько все сообщения перехватим и как надо обработаем".
> Слишком много нюансов выползает, ну нафик
Отвечу честно, нами для автора темы было расмотрено несколько вариантов решения возникшей перед ним задачи.
Автор темы человек с интелектом(я уверен!!!).
И сделает все самостоятельно, если уже не сделал. :)
А поскольку мы все с вами не стараемся раскрыть все свои карты,
поэтому ждать от меня "полного" решения напрасно.
← →
KSergey © (2009-01-14 08:24) [47]> oxffff © (13.01.09 21:43) [46]
> А поскольку мы все с вами не стараемся раскрыть все свои карты,
> поэтому ждать от меня "полного" решения напрасно.
ну про карты - это не правда какая-то, вроде никто ничего не скрывает, другое дело что полностью делать готовую реализацию всем лень, да и не надо автору, он сам не дурак :)
Я просто о том, что предложенный вами путь видится мне тупиковой: на простых примерах идея вроде рабочая, но потом нюансы разгребать замаешься.
← →
oxffff © (2009-01-14 19:51) [48]
> Я просто о том, что предложенный вами путь видится мне тупиковой:
> на простых примерах идея вроде рабочая, но потом нюансы
> разгребать замаешься.
Это ваше мнение, которое является только вашим не более и не менее. :)
← →
KSergey © (2009-01-15 11:00) [49]> oxffff © (14.01.09 19:51) [48]
> Это ваше мнение, которое является только вашим не более и не менее. :)
Безусловно, но оно подкреплено шишками от граблей :)
Окей, дома накидаю реализацию вашего метода (как я ее понял, специально портить ничего не буду, нгаоборот, приложу максимум усилий к качеству, обещаю). Завтра выложу тут и сообщу о найденных мною багах, которые я не знаю как исправить в таком подходе.
Пойдет?
← →
oxffff © (2009-01-15 11:44) [50]
> KSergey © (15.01.09 11:00) [49]
OK. :)
А я и все заинтересованные постараемся противостоять
:)
← →
KSergey © (2009-01-18 12:21) [51]Сроки я, как обычно, срываю.
Вот тут только исходники http://ifolder.ru/10086718
Вот тут исходники вместе с exe-файлом http://ifolder.ru/10086733
D7
Что сделал: простой классик, внутри содержит таймер, переключает по таймеру флажек. В конструктор классу передается TConponent, текстом хоторого хотелось бы мигать.
Для простоты под каждый мигаемый компонент отдельный экземпляр класса-мигателя, экземпляры класса-мигателя не удаляются, фик с ними, не в том пока суть.
Надо сказать, что споткнулся даже реньше чем ожидал, но рыть надоело.
Как воспроизвести траблу: запускаем, начинаем поверх окна приложения вошкать другим окном, через секунду (интервал таймера) изображения всех компонент пропадают (замечу: даже фон от TLabel, что не правильно и чего я и ожидал, но это фигня в сравнении с). Но, теперь процессор загружен на 100%, таймер более не срабатывает (судя по точкам остановки), явно у приложения не доходят "руки" до этих глупых WM_TIMER. Чем оноболее важным занято - не понял, предлагаю побеждать.
← →
KSergey © (2009-01-18 12:23) [52]Суда выложу классик мигателя:
unit Migalka;
interface
uses Windows, Messages, Controls, ExtCtrls, StdCtrls, SysUtils;
type
TMigalka = class(TObject)
private
FTimer: TTimer;
FControl: TControl;
FOldWndProc: TWndMethod;
FIsPaint: Boolean;
procedure NewWndProc(var Message: TMessage);
procedure DoFlash(Sender: TObject);
public
constructor Create(ACtrl: TControl);
destructor Destroy; override;
end;
implementation
type
TFreindGraphicControl = class(TGraphicControl);
{ TMigalka }
constructor TMigalka.Create(ACtrl: TControl);
begin
FControl := ACtrl;
FOldWndProc := FControl.WindowProc;
FControl.WindowProc := NewWndProc;
//
FIsPaint := True;
// Set Timer
FTimer := TTimer.Create(nil);
FTimer.OnTimer := DoFlash;
FTimer.Interval := 1000;
FTimer.Enabled := True;
end;
destructor TMigalka.Destroy;
begin
FTimer.Free;
inherited;
end;
procedure TMigalka.DoFlash(Sender: TObject);
begin
FIsPaint := not FIsPaint;
end;
procedure TMigalka.NewWndProc(var Message: TMessage);
function GetHDC: HDC;
begin
if FControl is TGraphicControl then Result := TFreindGraphicControl(FControl).Canvas.Handle
else if FControl is TWinControl then Result := GetDC(TWinControl(FControl).Handle)
else Result := 0;
end;
begin
if (Message.Msg = WM_PAINT) AND (NOT FIsPaint) then
begin
if NOT FIsPaint then
begin
Message.WParam := LongInt(GetHDC());
if Message.WParam <> 0 then
begin
Message.Msg := WM_ERASEBKGND;
FOldWndProc(Message);
Message.Result := 0;
end;
end;
end
else
FOldWndProc(Message);
end;
end.
← →
oxffff © (2009-01-19 15:24) [53]Я решил завязать с этим форумом.
Но ваш вопрос отвечу, чуть позже. :)
← →
KSergey © (2009-01-19 16:42) [54]> KSergey © (18.01.09 12:21) [51]
> Но, теперь процессор загружен на 100%,
> таймер более не срабатывает (судя по точкам остановки),
> явно у приложения не доходят "руки" до этих глупых WM_TIMER.
> Чем оноболее важным занято - не понял, предлагаю побеждать.
Да, замечу: оно не зацикливается в коде приложения. На крестик, например, нормально реагирует, закрывается.
Видимо беда в подмене WM_PAINT на WM_ERASEBKGND, видимо система не ожидает такого подвоха, а может в обработчике WM_ERASEBKGND вызывается что-то, что недопустимо по приходу WM_PAINT - оно ж особенное. Может его надо было все ж просто маскировать и все?
К стати, если его тупо сразу маскировать - то ексепшн типа "OS error" чего-то тама, не записал и не запомнил, сорри. Легко воспроизвести, если в конструкторе мигателя изначально FIsPaint присвоить False.
Собственно это все и ожидалось: подменять сообщения - это не просто, надо знать чего-то много, а иногда и просто невозможно (подозреваю, что не зря в MSDN написано "приложение само не должно посылать WM_PAINT"), при этом, как известно, обработчик WM_PAINT - оно несколько особенный в плане используемых функций для получения HDC. Видать система сама чего-то взводит перед его посылкой.
Но мне разбираться лень, сколько я пытался когда-то шаманить с подменой сообщений типа WM_PAINT - получал фигу, от того и считаю, что путь этот - гиблый.
← →
oxffff © (2009-01-26 12:08) [55]
> Но мне разбираться лень, сколько я пытался когда-то шаманить
> с подменой сообщений типа WM_PAINT - получал фигу, от того
> и считаю, что путь этот - гиблый
Вы не читаете свою почту. :(
У меня все работает. Пишите мне на почту.
TDynaHandler=function (var handle:HWND;var Rect:TRect):PRect of object;
TFlashHandler=class
State:byte;
NativeHandler:TWndMethod;
Timer:TTimer;
Control:TControl;
GetParams:TDynaHandler;
procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
procedure DefaultHandler(var Message);override;
procedure InterceptWndProc(var Message: TMessage);
procedure OnTimer(Sender: TObject);
function GetParams_WinControl(var handle:HWND;var Rect:TRect):PRect;
function GetParams_GraphicControl(var handle:HWND;var Rect:TRect):PRect;
constructor create(Control:TControl);
destructor destroy;override;
end;
{ TFlashHandler }
constructor TFlashHandler.create(Control: TControl);
begin
if not assigned(Control) then Raise Exception.Create("No control assigned");
if Control Is TWinControl then GetParams:=GetParams_WinControl
else GetParams:=GetParams_GraphicControl;
Timer:=TTimer.Create(nil);
Timer.OnTimer:=ontimer;
self.Control:=Control;
NativeHandler:=Control.WindowProc;
Control.WindowProc:=InterceptWndProc;
end;
procedure TFlashHandler.DefaultHandler(var Message);
begin
NativeHandler(Tmessage(message));
end;
destructor TFlashHandler.destroy;
begin
Timer.Free;
end;
function TFlashHandler.GetParams_GraphicControl(var handle:HWND;var Rect: TRect): PRect;
begin
rect:=Control.BoundsRect;
Handle:=TCustomLabel(control).parent.Handle;
result:=@Rect;
end;
function TFlashHandler.GetParams_WinControl(var handle:HWND;var Rect: TRect): PRect;
begin
Handle:=TWinControl(control).handle;
result:=nil;
end;
procedure TFlashHandler.InterceptWndProc(var Message: TMessage);
begin
Dispatch(message);
end;
procedure TFlashHandler.OnTimer(Sender: TObject);
var Handle:HWND;
prectA:prect;
RectA:Trect;
begin
State:=1-state;
pRectA:=GetParams(handle,RectA);
IF state=0 then
begin
InvalidateRect(handle,pRectA,false);
end
else
begin
InvalidateRect(Handle,pRectA,True);
end;
end;
procedure TFlashHandler.WMPaint(var Message: TWMPaint);
var Handle:HWND;
prectA:prect;
RectA:Trect;
EraseMessage:TWmEraseBkgnd;
begin
If state=1 then
begin
NativeHandler(Tmessage(Message));
end
else
begin
pRectA:=GetParams(handle,RectA);
EraseMessage.Msg:=WM_ERASEBKGND;
EraseMessage.DC:=GetDC(Handle);
Control.Parent.Dispatch(EraseMessage);
ValidateRect(Handle,pRectA);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
{Ýòè îáúåêòû íóæíî óäàëèòü}
TFlashHandler.create(shape1);
TFlashHandler.create(label1);
TFlashHandler.create(image1);
TFlashHandler.create(memo1);
TFlashHandler.create(edit1);
TFlashHandler.create(button1);
TFlashHandler.create(statusbar1);
end;
Заметим, что у контролов рисующих в WM_NCPAINT все рисуется, то есть по факту мигает только текст(см. memo).
Что касаемо мигания только текста в общем виде.
То и здесь у меня есть соображения.
← →
@!!ex © (2009-01-26 12:29) [56]Перекройте dll метод отрисовки текста на канву.
И все.
← →
webpauk © (2009-01-27 17:52) [57]может написать компонент на основе таймера с свойством "Объкты" типа TObjectList.
в объекты накидать нужное и мигать на событие таймера
← →
имя (2009-03-31 11:18) [58]Удалено модератором
← →
имя (2009-03-31 11:19) [59]Удалено модератором
Страницы: 1 2 вся ветка
Форум: "Основная";
Текущий архив: 2010.02.21;
Скачать: [xml.tar.bz2];
Память: 0.58 MB
Время: 0.008 c