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

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

Автор: 4t
Дата сообщения: 12.07.2010 23:16
Maks150988, Bonivur, нуда, что-т вроде того ... и все же я думал, что есть готовая функция как на С#, Dictionary...

В общем дело такое, строку нужно разложить на индексы позиций символов.
Получилось вот так:

Код:
const
alphabet := 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
Var
byt1 : array [0..15] of byte;
ind, ic : integer;
sym : char;
// data : string 16 символов
begin
for ind := 0 to 15 do byt1[ind]:= 0; // очистка массива
iс := 0;

while ic <> 16 do
begin
sym := data[ic+1]; // + 1 потому что позиция первого символа строки
for ind := 0 to 31 do
begin
if sym = alphabet[ind] then
begin
byt1[ic] := ind;
Break;
end;
end;
inc (ic);
end;
...
Автор: Bonivur
Дата сообщения: 13.07.2010 00:26
4t
Ну так бы сразу и сказал. Я думал у тебя массив строк или еще чего. А для отдельных символов есть такая функция. Pos называется.

function Pos(const substr: string; const str: string): Integer;

выдает порядковый номер вхождения символа или строки substr в строке str. Короче, создай новый проект. Кинь на форму одну Button и один ListBox. Далее пишешь код (после implementation) -


Код:
const
alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';

function GetPosition(const letter:Char):Integer;
begin
Result := Pos(letter,alphabet);
end;
Автор: 4t
Дата сообщения: 13.07.2010 11:50
Bonivur
Код походу самое оно, то что доктор прописал, вечером опробую.


Цитата:
P.S. ты алфавит не полный написал. Я дополнил.

Не, это не опечатка, мне полный алфавит не нужен, такой как в примере. Переписываю код с С и столкнулся с такими загвоздками... Почему сразу на С не пишу, потому что не особо в нём рублю )

А с этим что делать, критично чтоб индекс alphabet начинался с 0. Иначе много кода придется переделывать (.
4t

Цитата:
Константа или переменная типа string явно заданна (в данном случае alphabet ), можно задать чтобы индекс первого элемента начинался не с 1 что по умолчанию для строк, а с 0. Или придется делать массив: array [0..31] of char = ('_тутсимволы_') ?

Автор: Bonivur
Дата сообщения: 13.07.2010 17:08
4t

Цитата:
А с этим что делать, критично чтоб индекс alphabet начинался с 0. Иначе много кода придется переделывать (.

Первый символ строки в Дельфи имеет индекс 1 и тут ничего не поделаешь. А зачем тебе нужно "переделывать много кода"? Ты загадками не говори, а лучше сразу поставь задачу - что надо сделать и зачем. Может есть способ, о котором ты даже и не догадываешься, и он в сто раз лучше. Правильно заданный вопрос и подробное описание задачи - способствует получению быстрого и точного ответа!


Цитата:
Или придется делать массив: array [0..31] of char = ('_тутсимволы_') ?

Что-то я такого массива не увидел в твоем коде. Для чего он? Для чего тебе нужно, чтобы индекс первого элемента начинался с нуля?
Автор: 4t
Дата сообщения: 14.07.2010 23:14
Bonivur

Цитата:
Правильно заданный вопрос и подробное описание задачи - способствует получению быстрого и точного ответа!

Эх, золотые слова. Надо будет запомнить.

4t

Цитата:
Или придется делать массив: array [0..31] of char = ('_тутсимволы_') ?

Bonivur

Цитата:
Что-то я такого массива не увидел в твоем коде. Для чего он? Для чего тебе нужно, чтобы индекс первого элемента начинался с нуля?

Я имел ввиду, что если нельзя объявить константу или переменную alphabet : 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789' типа string с первым нулевым индексом, то можно сделать массив типа char с требуемыми символами и нулевым индексом: array [0..31] of char = (A,B,C,D,E,D и тд.)
По поводу для чего нужен нулевой индекс. Как уже упомянул переписываю код с Си. В Си коде "alphabet" с нулевым индексом, с индексами далее идут мат. операции и следовательно, если будет сдвиг +1 - результат на выходе будет другой. И варианты решения 1.)установить "alphabet" с нулевым индексом, что гораздо проще 2.) добавить ко всем обращениям к "alphabet" и "ИндексПозицииСимвола" смещение -1, что гораздо геморней. Вот по-этому индекс и хочу нулевой )

Автор: EugeneBoss3
Дата сообщения: 15.07.2010 01:15
Знатоки, помогите решить проблему. Для исключения мерцания пытаюсь по таймеру задержать отрисовку компонента, но не знаю как и в какой процедуре запустить таймер? У меня получается, что задержка срабатывает не ДО а ПОСЛЕ отрисовки компонента.
[more=Код]
// Вот сама процедура
procedure TMyLabel.TimerEvent(Sender: TObject);
begin
Sleep(FInterval); ???
// Генерируем событие OnTime компонента
if Assigned(FOnTimer) then FOnTimer(Self);
end;

procedure TMyLabel.CMMouseEnter(var Message : TMessage);
begin
// запускаем таймер
FTimer.Enabled := True;
inherited;
MouseEnter;
end;


procedure TMyLabel.CMMouseLeave(var Message : TMessage);
begin
// отключаем таймер
FTimer.Enabled := False;
inherited;
MouseLeave;
end;

procedure TMyLabel.MouseEnter;
begin
if Assigned(FOnMouseEnter)
then FOnMouseEnter(Self);
end;

procedure TMyLabel.MouseLeave;
begin
if Assigned(FOnMouseLeave)
then FOnMouseLeave(Self);
end;
[/more] Что я делаю не так?
Автор: Bonivur
Дата сообщения: 15.07.2010 08:24
4t

Цитата:
Я имел ввиду, что если нельзя объявить константу или переменную alphabet : 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789' типа string с первым нулевым индексом, то можно сделать массив типа char с требуемыми символами и нулевым индексом: array [0..31] of char = (A,B,C,D,E,D и тд.)

Если ты сделаешь вместо строковой константы массив символов Char, то не сможешь прменить функцию Pos. Она работает со строками. А в твоем случае не придется добавлять по всему коду смещение -1. Достаточно добавить его в одном месте, в функции GetPostion (которую я давал выше)


Код:
function GetPosition(const letter:Char):Integer;
begin
Result := Pos(letter,alphabet)-1;
end;
Автор: mdid
Дата сообщения: 15.07.2010 12:28
EugeneBoss3
не совсем понятно что вы хотите сделать...как вариант перехватывать OnPaint компонента
Автор: salexn1
Дата сообщения: 15.07.2010 13:14
>EugeneBoss3
А что должен делать компонент? Из того куска кода, ничего не понятно.
Автор: Frodo_Torbins
Дата сообщения: 15.07.2010 23:12
4t
На вашем месте я бы остановился на варианте с массивом. Тем более что вариант с простым циклом должен быть эффективнее в плане быстродействия чем функция Pos. Хотя вы вполне можете использовать и ее т. к. компилятор может спокойно преобразовать массив чаров в строку в коде типа "Pos('R', alphabet)".
Автор: EugeneBoss3
Дата сообщения: 15.07.2010 23:43
mdid

Цитата:
по таймеру задержать отрисовку компонента

Мне нужно отследить срабатывание таймера и только после этого перерисовать компонент.
salexn1

Цитата:
А что должен делать компонент?

При вхождении курсора мыши в область компонента запустить таймер, после выхода из области остановить таймер
Автор: Bonivur
Дата сообщения: 16.07.2010 00:37
Frodo_Torbins
В новых версиях Delphi (начиная с 2006) многие процедуры и функции для работы со строками были переписаны на ассемблере. Скорость работы значительно улучшена. Почитайте Канту. Сами же советовали
Автор: mdid
Дата сообщения: 16.07.2010 08:15
EugeneBoss3
я так пологаю самый верный способ будет написать свой компонент на основе текущего...перехватить его событие OnPaint и перерисовывать когда какая то переменная= true..которая в свою очередь будет выставляться в true когда будет курсор на компоненте..так же попробуйте выставить форме DoubleBuffered:=true
Автор: SIgor33
Дата сообщения: 16.07.2010 10:41
Подскажите кто-нибудь работал с cryptopro через delphi? Интересуют вопросы по ЭЦП. Если есть наработки поделитесь!
Автор: andrewtishkin
Дата сообщения: 16.07.2010 11:21
SIgor33
С этой темой на Delphi в сети туго... Несколько полезных ссылок (есть и архив с кой-какими делфи-примерами) и книг упоминали тут: Работа с CryptoAPI в Delphi или C++ Builder
Автор: Frodo_Torbins
Дата сообщения: 16.07.2010 22:36
Bonivur
Pos все же оптимизирован на поиск подстроки в строке, а не одного символа. Если же нужно найти всего один символ, то с простым циклом мало что сравнится.
Но у автора изначального вопроса все еще проще - строка задана изначально и отсортирована. Вполне можно обойтись парой if-ов и одним Ord-ом.
Автор: EugeneBoss3
Дата сообщения: 17.07.2010 10:18
mdid

Цитата:
я так пологаю самый верный способ будет написать свой компонент на основе текущего


Цитата:
Мне нужно отследить срабатывание таймера

Как раз тем и занимаюсь что пишу новый компонент на основе текущего, но не знаю как отследить срабатывание таймера т.к. OnTimer не булевый
Автор: Frodo_Torbins
Дата сообщения: 17.07.2010 12:20
EugeneBoss3

Цитата:
но не знаю как отследить срабатывание таймера т.к. OnTimer не булевый

Причем тут булевость о_О ? OnTimer - это событие. Подробности: Пособие по написанию компонентов на Дельфи.
Автор: Bonivur
Дата сообщения: 17.07.2010 19:16
Frodo_Torbins
Да уж по этому только и учиться. Прямое обращение к полям в private без properties Энкапсуляция идет лесом ...
Автор: Frodo_Torbins
Дата сообщения: 17.07.2010 20:42
Bonivur
Хотел сначала дать ссылку на Жизнь и смерть в режиме run-time, но королевство в последнее время так колбасит, что пришлось искать альтернативу.
Автор: Bonivur
Дата сообщения: 18.07.2010 00:17
Вопрос такой - диалог TSaveTextFileDialog имеет список Encodings. Они что изначально ни привязаны ни к каким объектам (я имею в виду, конечно, кодировки TEncodings)? Просто пустышки что ли? Чтобы сохранить файл в нужной кодировке приходится вручную прописывать AssignObects как описано [more=в документации]
Код:
procedure TForm1.FormCreate(Sender: TObject);
var
encodings : TStrings;
begin
// Create a new string list that holds encoding info.
encodings := TStringList.Create();

// Add some encodings to the list.
encodings.AddObject('ASCII', TEncoding.ASCII);
encodings.AddObject('UNICODE', TEncoding.Unicode);
encodings.AddObject('UTF8', TEncoding.UTF8);

SaveTxtDlg.Encodings.Assign(encodings);

end;
Автор: EugeneBoss3
Дата сообщения: 18.07.2010 03:10
Frodo_Torbins
Как же отследить срабатывание таймера? Можно пример?
Автор: Bonivur
Дата сообщения: 18.07.2010 09:00
EugeneBoss3

Цитата:
Как же отследить срабатывание таймера? Можно пример?

Хотя вопрос и не мне был задан, но в примере, который дал Frodo_Torbins -
[more=все подробно описано]

Код:
unit CountBtn;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls;

var Timer: TTimer;

type
TCountBtn = class(TButton) //это название вашего компонента - TCountBtn
.....

implementation

.....

constructor TCountBtn.Create(aowner:Tcomponent);
begin
inherited create(Aowner);
Timer:=TTimer.Create(self);
Timer.Enabled:=true;
Timer.OnTimer:=OnTimer;//какой метод вызывать по событию OnTimer
Timer.Interval:=10000;//здесь задаете интервал
end;

procedure TCountBtn.OnTimer(Sender: TObject);
begin
FCount:=FCount*2;//любое ваше действие
end;
Автор: Frodo_Torbins
Дата сообщения: 18.07.2010 09:43
Bonivur

Цитата:
Вопрос такой - диалог TSaveTextFileDialog имеет список Encodings. Они что изначально ни привязаны ни к каким объектам (я имею в виду, конечно, кодировки TEncodings)? Просто пустышки что ли?

В dfm ссылки на ассоциированные со строками объекты не сохранишь. А как имея локализованую строку текста (к примеру #32431#25991#26412) сопоставить с ней нужную кодировку?
Автор: Bonivur
Дата сообщения: 18.07.2010 09:53
Frodo_Torbins
Зачем в dfm? Все делается в коде компонента ([more=и уже сделано]

Код:
//выдрано из ExtDlgs.pas, в котором прописан TSaveTextFileDialog
function StandardEncodingFromName(const Name: string): TEncoding;
begin
Result := nil;
if Name = SANSIEncoding then
Result := TEncoding.Default
else if Name = SASCIIEncoding then
Result := TEncoding.ASCII
else if Name = SUnicodeEncoding then
Result := TEncoding.Unicode
else if Name = SBigEndianEncoding then
Result := TEncoding.BigEndianUnicode
else if Name = SUTF7Encoding then
Result := TEncoding.UTF7
else if Name = SUTF8Encoding then
Result := TEncoding.UTF8;
end;
Автор: Frodo_Torbins
Дата сообщения: 18.07.2010 10:10
Bonivur
Цитата:
А насчет локализованной строки текста - мне это не надо кодировку выставляет пользователь вручную в диалоге SaveTextFileDialog.
Вам это не надо, кому то надо, а VCL пишется так, чтобы удобно было всем. Для тех, кого устраивает дефолтный вариант вон даже специальную функцию придумали.

Цитата:
Все хорошо, все работает, кроме одного - кодировка UTF-7 не сохраняется ни в какую.
Я надеюсь вы не простой 'Hello world!' сохраняете?
Автор: Bonivur
Дата сообщения: 18.07.2010 10:32
Frodo_Torbins

Цитата:
А как имея локализованую строку текста (к примеру #32431#25991#26412) сопоставить с ней нужную кодировку?

Определить кодировку текста в Memo можно без всяких процедур и функций. Это UTF16-LE. Или я не так понял Ваш вопрос?

А сохраняю я конечно, не "Hello, world!" . Простой текст на русском языке.
Автор: Frodo_Torbins
Дата сообщения: 18.07.2010 10:56
Bonivur
Цитата:
Но было бы просто отлично если можно было бы проверять есть ли в заданном тексте в Memo символы, которых нет в дефолтной кодовой странице компьютера пользователя (например, для России это обычно Win-1251, для запада 1252) и если такие символы имеются, то сохранять в Unicode, иначе - сохранять в ANSI.
Юзайте WideCharToMultiByte напрямую, последний параметр вам в помощь. Но имхо если не планируется сохранять логи >100Мб то это лишние заморочки.

Цитата:
Определить кодировку текста в Memo можно без всяких процедур и функций. Это UTF16-LE. Или я не так понял Ваш вопрос?
Я о том, что SaveTextFileDialog1.Encodings[1] в Китае может быть совсем не 'ANSII', а какие нибудь иероглифы, которые означают тоже самое. И вот, как бедная VCL без помощи программиста должна определить, что требуется TEncoding.ASCII?
Тем более что дефлотный вариант не приемлем даже в Америке с точки зрения дружественности интерфейса. И по хорошему вместо 'ANSII' должно быть что то вроде 'Plain text', а вместо 'UTF8' - 'Unicode'.

Цитата:
А сохраняю я конечно, не "Hello, world!" . Простой текст на русском языке.
А чем тогда смотрите?
Автор: Bonivur
Дата сообщения: 18.07.2010 11:17
Frodo_Torbins

Цитата:
Юзайте WideCharToMultiByte напрямую, последний параметр вам в помощь. Но имхо если не планируется сохранять логи >100Мб то это лишние заморочки.

Почему лишние? Сохранять все в Unicode? А если система до WinXP?


Цитата:
Я о том, что SaveTextFileDialog1.Encodings[1] в Китае может быть совсем не 'ANSII', а какие нибудь иероглифы, которые означают тоже самое. И вот, как бедная VCL без помощи программиста должна определить, что требуется TEncoding.ASCII?
Тем более что дефлотный вариант не приемлем даже в Америке с точки зрения дружественности интерфейса. И по хорошему вместо 'ANSII' должно быть что то вроде 'Plain text', а вместо 'UTF8' - 'Unicode'.

Так речь и не шла об автоматическом определении кодировки, а о том, что пользователь открыв диалог SaveTextFileDialog выбирает в нижнем поле желаемую кодировку и файл в ней и сохраняется. Я ожидал такого поведения от этого компонента. Но это оказалось не так и надо было использовать функцию из модуля ExtDlgs.pas , чтобы добиться этого. В документации про это ни слова.

Цитата:
А чем тогда смотрите?

AkelPad и WordPad.
Автор: EugeneBoss3
Дата сообщения: 18.07.2010 12:00
Bonivur
Все что в примере подробно описано мною сделано
// Вот моя процедура
procedure TMyLabel.TimerEvent(Sender: TObject);
begin
Sleep(FInterval); ???
// Генерируем событие OnTime компонента
if Assigned(FOnTimer) then FOnTimer(Self);
end;
В свое примере я попытался сделать задержку, но задержка получилась ПОСЛЕ отрисовки. Вот я и прошу помочь разобраться где я делаю не так?

Страницы: 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374

Предыдущая тема: MPO File


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