Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Вопросы по Delphi (до версии 2009) - часть 5

Автор: greenpc
Дата сообщения: 04.08.2009 09:23
DmitryKz
а что сложного написать самому, типа такого
Код:
var
bFound: array[0..5] of Byte=(2,1,3,4,5);
bRead: array[0..1024] of Byte;
begin
BlockRead(FromFile, bRead, SizeOf(bRead), NumRead);
result:=-1;
if NumRead< SizeOf(bFound) then exit;
for i := 0 to NumRead - 1 - SizeOf(bFound) do begin
if bRead[i]<>bFound[0] then continue;
YesFound := True;
for j := 0 to SizeOf(bFound) - 1 do
if bRead[i+j] <> bFound[j] then YesFound := False;
if YesFound then Break;
end; // for
result :=i;
Автор: StalkerSoftware
Дата сообщения: 04.08.2009 15:18
Hi всезнающий All,

Нашел на www.torry.ru пару весьма полезных компонент для раскраски или подчеркивании слов в обычном TMemo, причем что очень ценно они наследуются от обычного TMemo, что очень упрощает их интеграцию в свою библиотеку да и под D2009 они тоже работают.
Нужны они мне для выделения слов для проверки орфографии.

Вот ссылки на них:
Highlight within TMemo
Live spelling memo editor

В принципе они работают достаточно неплохо.
Для перерисовки из за изменений текста или из за других событий они используют сообщения
WM_PAINT, WM_SIZE, WM_MOVE, WM_VSCROLL, WM_MOUSEWHEEL.
и перекрывают обработчик
procedure Change; override

Но если в этом Memo выделить раскрашенный текст, то раскраска пропадает.
Вопрос: Какое событие или сообщение можно использовать для TMemo, что бы вовремя или после выделения текста можно было бы вызвать из него Invalidate для повторной раскраски текста ?
Ну и может быть All, посоветует какие ее события или сообщения надо обрабатывать
для TMemo, что бы не пропадала (или не портилась) раскраска текста ?

P.S. По поводу RichEdit (его наследников) или RichView, SynEdit, SyntaxMemo от TMS или FastReport и других подобных навороченных компонентах я в курсе,
Но для моего случая (т.е. только для подчеркивание или раскраски неправильного слова при проверке орфографии) использование подобных компонент ИМНО излишне, все равно что из пушки по воробьям стрелять.
Автор: data man
Дата сообщения: 04.08.2009 16:56
StalkerSoftware
Самый простой способ - в конце события MouseUp (можно и в KeyUp тоже) дописать

Код: if SelLength = 0 then invalidate;
Автор: StalkerSoftware
Дата сообщения: 04.08.2009 18:16
data man

Цитата:
Самый простой способ - в конце события MouseUp (можно и в KeyUp тоже) дописать

Код:
if SelLength = 0 then invalidate;

Спасибо за подсказку.


Цитата:
P.S. IMHO, в этих компонентах ужасная реализация - слишком мерцает.

После того как я написал первый пост и еще немного их потестировал (реализация раскраски у них почти одинаковая), то тоже увидел это мерцание. Особенно оно заметно при частом скролировании и быстром наборе текста.

Может ты или All может что то посоветовать по улучшению реализации WMPaint в этом компоненте ?

P.S. Я потратил кучу времени в инете и лучшее, что я смог найти (т.е. что бы была простая раскраска текста в меmo и ничего лишнего кроме нее), это как раз Highlight TMemo. Он весьма небольшой, весь архив с примером 20 кб.

Автор: data man
Дата сообщения: 04.08.2009 18:53
StalkerSoftware
Вот это не подойдет ? Ссылка

P.S. Просьба - не нужно больше на "ты".
Автор: murkovich
Дата сообщения: 04.08.2009 22:17
StalkerSoftware

Цитата:
Может ты или All может что то посоветовать по улучшению реализации WMPaint в этом компоненте ?

Дело там не столько в WMPaint, а в том, что на любое событие делается Invalidate на весь контроль. А там уже трудно без мерцания. Встроенный windows контроль по максимальному оптимизирован на этот счет, и скорее всего дейстует еще хитрее чем просто отсекание той части, которая заведомо не менялась.

Но тут такая проблема, что в принципе раскраска всего текста (в т.ч. до курсора) может поменятся из-за одного вставленного или удаленного символа. Поэтому простая оптимизация и полное разделение логики тут вряд ли получится - если хочется красиво, то придется делать сложный алгорифм, который контроллирует всё - и ввод, и размещение, и раскраску (имхо).

Посмотри SynEdit - может идеи пригодятся.
Автор: ShIvADeSt
Дата сообщения: 05.08.2009 01:09
StalkerSoftware

Цитата:
Может ты или All может что то посоветовать по улучшению реализации WMPaint в этом компоненте ?

Чтобы уменьшить мерцание в этом (или любом другом компоненте) надо использовать offscreen bitmaps, то есть вначале делается копия изображения на битмапе в памяти, рисуется все что надо на нем, а потом выводится на контекст контрола (TCanvas в дельфи). Только в этом случае мерцание можно подавить или уменьшить. НО при этом придется ставить собственные обработчики на ВСЕ события при которых происходит перерисовка контрола. Если уровень знания Дельфи и обработки сообщений (messages) невысок, то плохо.
murkovich

Цитата:
Встроенный windows контроль по максимальному оптимизирован на этот счет, и скорее всего дейстует еще хитрее чем просто отсекание той части, которая заведомо не менялась.

Абсолютный бред помогал одному члену руборда переделывать OwnerDrawListBox так вот если делать отрисовку в WM_DRAWITEM то идет нехилое мерцание при скроллинге, при этом данное сообщение СПЕЦИАЛЬНО предназначено для отрисовки подобных случаев.

Цитата:
то придется делать сложный алгорифм, который контроллирует всё - и ввод, и размещение, и раскраску (имхо).
с этим согласен, единственное НО - алгоритм не то чтобы сложный, он просто нудный Ставить обработчик на все события, смотреть как ДАННОЕ событие должно отрабатывать и как его надо заставить работать, достаточно кропотливый труд выходящий за рамки типовых вопросов.
data man

Цитата:
P.S. Просьба - не нужно больше на "ты".

ээээ, тут как бы принято на "ты" обращаться, так как на форуме все равны, то Выкать не принято - коробит как то.
2 StalkerSoftware если сам не доработаешь контрол - то создавай отдельную тему, по превращению Мемо в раскрашенный мемо. В рамках типовых вопросов разбирать решение задачи некорректно, достаточно специфичный вопрос.

Автор: Frodo_Torbins
Дата сообщения: 05.08.2009 13:13

Цитата:
Чтобы уменьшить мерцание в этом (или любом другом компоненте) надо использовать offscreen bitmaps, то есть вначале делается копия изображения на битмапе в памяти, рисуется все что надо на нем, а потом выводится на контекст контрола (TCanvas в дельфи).

Этот режим вроде свойством DoubleBuffered включается.
Автор: DmitryKz
Дата сообщения: 05.08.2009 17:47

Цитата:
а что сложного написать самому, типа такого

Ну да, если как учебную задачу ставить, то, конечно, можно и нужно наваять самому. Но вот ситуация, если нужно найти несколько сотен таких последовательностей, то как-то и встает вопрос и о времени и эффективности каких-то решений. А эта задача, насколько я понимаю, нетривиальная. Вот и хотелось бы узнать о существовании эффективных реализаций такого поиска. Даже не первого совпадения, а всех совпадений.
Автор: data man
Дата сообщения: 05.08.2009 18:33
DmitryKz
Один из самых известных алгоритмов поиска - Бойера-Мура-Хорспула.
Пример реализации http://angusj.com/delphi/searches.html

Ну а описания самих алгоритмов:
http://ru.wikipedia.org/wiki/Категория:Алгоритмы_поиска
http://en.wikipedia.org/wiki/Category:Search_algorithms

Автор: StalkerSoftware
Дата сообщения: 05.08.2009 20:02
data man

Цитата:
Вот это не подойдет ?

За ссылку спасибо, но это не годится. Тут та же проблема, что и у остальных полобных контролов - этот RichMemo порожден от TCustomControl. Мне же надо, что бы он был порожден от TMemo или в крайнем случае от TCustomMemo.

У меня есть своя библиотека. В ней есть контролы порожденные от TEdit и TMemo в которые я добаил некоторую свою функциональность.
Сейчас мне понадобилось добавить в программу проверку орфографии. Сама проверку у меня уже сделана. И сейчас мне надо научиться выделять слова именно в наследниках TMemo и TEdit.
И именно по этому меня и привлек Highlight TMemo, так как он во первых порожден от TMemo и следовательно я легко смогу внедрить его код в своих наследников, а во вторых кроме выделения слов в нем нет лишний функциональности, что так же упрощает его внедрение. И если бы он еще не мерцал, то был бы вообще идеальным для моего случая.
А компоненты порожденные от TCustomControl для подобного внедрения (переноса функционала) слишком сложны для меня и зачастую в них присутствует еще куча ненужного мне функционала.

ShIvADeSt

Цитата:
Если уровень знания Дельфи и обработки сообщений (messages) невысок, то плохо.

Хотя я работаю с Delphi начиная еще с D1, но я больше прикладник и подобные сложные компоненты с обработкой системных сообщений пишу достаточно редко.
Так что к сожалению, знаний именно в этой области у меня не очень высокие.


Цитата:
2 StalkerSoftware если сам не доработаешь контрол - то создавай отдельную тему, по превращению Мемо в раскрашенный мемо. В рамках типовых вопросов разбирать решение задачи некорректно, достаточно специфичный вопрос.

Пожалуй так и сделаю. Надеюсь ты туда тоже заглянешь

Добавлено:
Frodo_Torbins

Цитата:
Этот режим вроде свойством DoubleBuffered включается.

Попрбовал я включить этот режим у Memo (Memo1.DoubleBuffered := True) в Create формы - к сожалению не помогло, Memo все равно мерцает.
Автор: ShIvADeSt
Дата сообщения: 06.08.2009 00:50
Frodo_Torbins

Цитата:
Этот режим вроде свойством DoubleBuffered включается.

Я знал про это свойство, но искренне считал что оно только у формы есть . Тогда по сути задача про мерцание сводится к включению этого свойства у контрола и все.
Автор: Grande
Дата сообщения: 06.08.2009 08:38
Доброе утро, All!
Не пойму, где затык - вываливается с Access Violation, блин:


Код: asm
TEST EAX,EAX
JE @@qt
TEST EDX,EEX
JE @@zq
PUSH EBX
PUSH ESI
DEC ECX
JL @@m0
MOV EBX,[EDX-4]
SUB EBX,ECX
JLE @@m0
ADD EDX,ECX
MOV ESI,[EAX-4]
CMP EBX,ESI
JL @@m0
@@lp: DEC ESI
JS @@m1
MOVZX EBX,BYTE PTR [EAX+ESI]
MOVZX ECX,BYTE PTR [EDX+ESI]
CMP BL,CL
JE @@lp
MOV BL,BYTE PTR [EBX+ToUpperChars]
XOR BL,BYTE PTR [ECX+ToUpperChars]
JE @@lp
@@m0: POP ESI
POP EBX
@@zq: XOR EAX,EAX
RET
@@m1: POP ESI
POP EBX
@@qt: MOV EAX,1
end;
Автор: akaGM
Дата сообщения: 06.08.2009 09:04
Grande
вообще-то по асму спец.топ есть...
а ты б ещё сюда бинарник вкатил, и откуда уверенность, что дело в этом огрызке кода?

Код: TEST EDX,EEX
Автор: Grande
Дата сообщения: 06.08.2009 09:06
akaGM

Цитата:
вообще-то по асму спец.топ есть...

Прошу прощения - не знал (думал, раз кусок в Delphi - значит, сюда).

Цитата:
и что это за хрень?

Сам удивляюсь Старею, наверное...
Спасибо огромное.
Автор: akaGM
Дата сообщения: 06.08.2009 09:12
Grande
интересно как в дельфях это компилировалось вообще...
Автор: Grande
Дата сообщения: 06.08.2009 09:16
akaGM
Да никак не скомпилировалось - падает и всё.
Жарко, блин, отсюда и невнимательность, похоже.
Автор: akaGM
Дата сообщения: 06.08.2009 09:24
Grande

Цитата:
отсюда и невнимательность, похоже.

чья, дельфийская? гы-гы
dcc32 -- наше всё...
Автор: delover
Дата сообщения: 06.08.2009 11:39
А неподскажете, у меня не работает в проге компонент. Сам то компонент работает, а в проге, мне кажется из-за этой функции:

Код: function GetModulePath(const Module: HMODULE): string;
var
L: Integer;
begin
L := MAX_PATH + 1;
SetLength(Result, L);
L := Windows.GetModuleFileName(Module, Pointer(Result), L);
SetLength(Result, L);
end;
Автор: data man
Дата сообщения: 06.08.2009 11:59
delover
Вряд ли дело в этой функции - этот код очень часто используется - в JCL, например.
Во всяком случае:

Код: WriteLn(GetModulePath(HInstance));
Автор: delover
Дата сообщения: 06.08.2009 13:31
data man
А Pointer(Result) это Addr(Result[0]) или A(Result[1])?

У меня вопрос общий по квесту:
http://www.delphikingdom.com/quintana/quintana.asp?ItemID=10

Цитата:
Вопрос №4
Некоторые процедуры и функции (например, TApplication.MessageBox) имеют параметры, через которые передаются флаги (для MessageBox это параметр Flags и флаги MB_OK, MB_CANCEL, MB_HELP и т.д.). Если необходимо передать несколько флагов, как это МОЖНО сделать?
...
2)Объединив флаги оператором +
3)Объединив флаги оператором or

спецом ответил 2. - Баян. Я думал что писать MB_OK+MB_ICONASTERISK можно.
Но сказано что я ответил неправильно:

Цитата:
...Что же касается использования для этих целей операции +, которое иногда встречается в примерах в интернете, то в большинстве случаев это работает и даёт правильный результат...

Оказывается не можно, а можно.
Автор: data man
Дата сообщения: 06.08.2009 13:45
delover
Обращение к нулевому элементу строки в последних версиях не работает.
Это справедливо только для ShortString.
Так что
Код: Pointer(Result) равен Addr(Result[1])
Автор: Frodo_Torbins
Дата сообщения: 06.08.2009 14:13
delover
Там же вроде сказано, что плюс не работает, когда есть флаг, устанавливающий несколько бит, один из которых также устанавливает другой флаг. Допустим у нас есть флаг All_Func=$F; и еще один Func1=$1; Теперь сравните результат двух выражений:
A := All_Func or Func1;
B := All_Func + Func1;
Полезность or я думаю очевидна.
Автор: delover
Дата сообщения: 06.08.2009 14:18
data man
А почему не работает? У меня в опциях проекта есть Huge Strings. Честно говоря за Jcl я спокоен. Но так я чего то не помню как эту опцию в программе пишут. Я только галочку могу посмотреть.


Цитата:
Оказывается не можно, а можно.

12

Цитата:
procedure TForm2.Button1Click(Sender: TObject);
begin
Form2.Label1.Caption := 'Кнопка нажата';
end;

3 Здесь нельзя обращаться к компоненту Label1 через переменную Form2
...
Автор: data man
Дата сообщения: 06.08.2009 14:23
delover
Long strings включены по умолчанию.
Не совсем понятно что конкретно не работает - дело не в приведенной функции.
Можно поподробнее ?
Автор: delover
Дата сообщения: 06.08.2009 14:56
data man
Мне пока трудно сказать, выполняется на виртуалке без отладки. Я подумал что из за этой функции.

зы
про классы я вообще облажался. На вопрос что неправильно

Цитата:

e := te.create
raise e;
e.free;

Я ответил что всё правильно. оказалось возможна утечка памяти.


Цитата:
x.free
if pointer(x)=nil then showmessage('nil');

интересно как это будет в дотнет версии...
Автор: data man
Дата сообщения: 06.08.2009 15:04
delover

Цитата:
x.free
if pointer(x)=nil then showmessage('nil');

Именно поэтому и рекомендуется использовать FreeAndNil(x).
Автор: Frodo_Torbins
Дата сообщения: 06.08.2009 16:11
delover
Там ведь в комментарии наверняка написано, что Form2.Label1 может дать ошибку, когда создано несколько экземпляров TForm2. Вообще, судя по всему, квинтану писали люди, которым в первую очередь важна надежность, и лично мне такой подход нравится.
Автор: delover
Дата сообщения: 06.08.2009 16:42
Frodo_Torbins

Цитата:
в первую очередь важна надежность, и лично мне такой подход нравится.

Мне тоже нравится надёжность, но по поводу вопросов которые выше у меня впечатление другое. Если я буду врать ученикам своим ученикам, то вряд ли добъюсь надёжности. Нельзя <> можно. Привожу пример подходящий допустим для маленького коллектива:

Цитата:

procedure TForm2.Button1Click(Sender: TObject); ...Caption := 'Кнопка нажата';
...

procedure TForm2.WMActivate;
begin
inherited
try
Form2.ButtonClick1(DataModule1);
except
ShowMessage(
'Друг мой, если ты увидел это сообщение то значит '+
'ты неправильно юзаешь окно и тебе либо придётся всё переделать '+
'либо юзать её правильно. Так как окно ты действительно создал но оно '+
'не уникально или не присвоено переменной Form2. Что было бы если бы '+
'свою ошибку ты узнал через пол года?');
end;
end;


Добавлено:
Frodo_Torbins
Второе.

Цитата:
e := tsomeclass.create
strtoint('222');
........... raise e; /................
...
e.free;

tsomeclass.create не отличается от strtoint. зачастую, чтобы не лазить везде по коду и исправлять, можно объявить одноимённую функцию strtoint ровным счётом так же просто как и tsomeclass.create.
Автор: Ramazan
Дата сообщения: 06.08.2009 18:43
Frodo_Torbins
Тем не менее, определенные вопросы сформулированы так, что допускают варианты толкований. Я, например, так и не понял, почему я, с их точки зрения, не могу корректно создать поток с использованием CreateThread. А вообще, тесты хороши, пожалуй, начну их использовать при найме программистов

Страницы: 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768

Предыдущая тема: Clipper 5


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.