Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
{&#221;&#242;&#232; &#238;&#225;&#250;&#229;&#234;&#242;&#251; &#237;&#243;&#230;&#237;&#238; &#243;&#228;&#224;&#235;&#232;&#242;&#252;}
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
2-1261424330
Drowsy
2009-12-21 22:38
2010.02.21
ComponentName.


15-1260369295
xayam
2009-12-09 17:34
2010.02.21
Вопрос по SQL


15-1260806036
{RASkov}
2009-12-14 18:53
2010.02.21
3G Modem


15-1260782130
Максимильянов
2009-12-14 12:15
2010.02.21
кодировка в Opera


1-1222891708
RustB
2008-10-02 00:08
2010.02.21
Копирование с шифрованием





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский