Magic Team

Объявление

Сайт переехал сюда: http://magicteam.net
Новый форум: http://magicteam.net/forum

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Magic Team » Программирование » Delphi


Delphi

Сообщений 91 страница 120 из 151

91

Этот код по идее должен работать быстрее с большими файлами. Замены и добавления выделены жирным шрифтом.

var
Result1: String;
S, Minus: integer;
byteArray : array[1..2] of byte;
count  : Integer;
Stream: TFileStream;
i: longword;

begin
Result1 := '' ; S:=0; Minus :=0;

// С помощью стандартного диалога получаем имя файла
if not OpenDialog1.Execute then
Exit; // Пользователь отказался выбрать файл
// Пытаемся открыть файл
try
Stream:=TFileStream.Create(OpenDialog1.FileName,fmOpenRead);
except
// Файл нельзя открыть:
ShowMessage('Невозможно открыть файл ' + OpenDialog1.FileName) ;
Exit;
end;

try
Stream.Seek(S,soFromBeginning);
while Stream.Size>=i do begin
Stream.Read(byteArray, 1); //читаем файл по 1 символу

S:=S+1;//счётчик символов

if  GridOriginal.Cells[(LoNibble(byteArray[1]))+1,(HiNibble(byteArray[1]))+1] <> '' then
Result1 :=  Result1 + GridOriginal.Cells[(LoNibble(byteArray[1]))+1,(HiNibble(byteArray[1]))+1]; //если символ есть в таблице - добавляем его в результат

if  GridOriginal.Cells[(LoNibble(byteArray[1]))+1,(HiNibble(byteArray[1]))+1] <> '' then
Minus := Minus+1; //если символ есть в таблице - увеличиваем переменную Minus

if  (SpinEdit2.Value < Minus+1) and (GridOriginal.Cells[(loNibble(byteArray[1]))+1,(HiNibble(byteArray[1]))+1] = '') and (Result1 <> '') then
Original.Lines.Add (inttostr(S-Minus)+' '+Result1); // Печатаем результат если последовательность символов, которые есть в таблице, закончилась

if  GridOriginal.Cells[(LoNibble(byteArray[1]))+1,(HiNibble(byteArray[1]))+1] = '' then
Result1 := ''; //обнуляем результат если прочитанного символа нет в таблице
if  GridOriginal.Cells[(LoNibble(byteArray[1]))+1,(HiNibble(byteArray[1]))+1] = '' then
Minus := 0;

inc(i);
   end;
finally
Stream.Free; // Закрываем файл
end;

end;

0

92

Интересно! Провёл небольшую проверку ;о)

Открывал файл 11 Мб и получил вот такие результаты:

мой код: 3 минуты 11 секунд - 3 минуты 30 секунд
ваш код: 3 минуты 25 секунд - 3 минуты 43 секунд

При работе программы видно, что она загружает текст порциями, а потом уже шерстит его... Примерно то же самое я делал, когда принимал byteArray : array[1..100] of byte;

А если я создам 2 потока - разве это повлияет на скорость программы? 1 поток будет есть 50% ресурсов компьютера как и второй, разве не так? Блин, как же программимты это делают???

Наверное нужно сам алгоритм "шерстения" изменить на более удачный...

Отредактировано guyver (2007-05-25 21:02:59)

0

93

И ещё - возможно ли сделать так, чтобы прога кушала не 100% ресурсов компа, а 50%? А то у меня в особо тяжёлых случаях вообще возникает переполнение буфера...
П.С. гружу тот же файл 11 Мб - всеми правдами и неправдами пока удалось добиться самой высокой скорости 1 минута 30 секунд ;о) Это если в Мемо вынимать, а если в другие компоненты - то скорость может сильно измениться... Например если в грид - процесс может вообще через минуту зависнуть...

Отредактировано guyver (2007-05-27 00:19:14)

0

94

TFileStream работает медленнее, чем File. А загружать все 40 мб в память не надо. Грузи только блоки, с которыми собираешься работать.

+1

95

Привет всем! Опять вопросы:

1. Есть у меня диалог OpenDialog1 - им я указываю, какой файл я буду
открывать (первая кнопка)
2. Есть у меня диалог OpenDialog2 - им я указываю, какой программой я
открою указанный файл (вторая кнопка)
3. И наконец третья кнопка, при нажатии на неё:

if (ShellExecute(0, nil,
PChar(ExtractFileName(OpenDialog1.FileName)),PChar(ExtractFileName(OpenDialog2.FileName)),
nil, SW_NORMAL))<=32
then MessageBox(0,'Указанная вами программа не обнаружена!','Ошибка
запуска программы!', MB_OK);

Так вот - если программа и файл лежат в одной директории, то всё прекрасно
работает, т.е. нажимаю кнопку 1 и выбираю например текстовой файл, нажимаю
кнопку 2 и выбираю например ВОРД, а при нажатии на кнопку 3 файл
открывается в ВОРДЕ. НО!!!! Если сам файл и открывающая его программа
лежат в разных директориях - ничего не работает!!! Помогите кто-нибудь,
как это исправить?

Если я буду указывать путь полностью, не обрезая:
PChar(OpenDialog1.FileName),PChar(OpenDialog2.FileName), nil, SW_NORMAL))<=32
то файл будет открываться не той программой, которая указана, а той, что винда по-умолчанию пользуется..

В общем как я только не экспериментировал - либо открывается прога, но файл нет, либо наоборот...

А таким макаром: if (ShellExecute(0, nil, PChar(OpenDialog2.FileName), PChar(ExtractFileName(OpenDialog1.FileName)), nil, SW_NORMAL))<=32
вроде работает, НО только если сначала открыть файл в той же папке, что и программа, с помощью которой он будет открыт, потом можно открывать любые файлы в любом месте... Блин, плохо быть глупым!!!

0

96

if (ShellExecute(0, nil,
PChar(ExtractFileName(OpenDialog1.FileName)),PChar(ExtractFileName(OpenDialog2.FileName)),
nil, SW_NORMAL))<=32

Здесь надо указывать полный путь, а не только имена файлов. И установить перед этим рабочую директорию с помощью ChDir, если я не ошибаюсь.

0

97

Спасибо, разобрался ;о)

0

98

Пожалуйста, помогите, никак не получается. Пытаюсь переписать свою Поганку (http://user.rol.ru/~bhlady/programs/vp.htm) на Delphi 7 (с добавлением новых функций), а также создать похожую на неё программу сравнения файлов. К сожалению, никак не получается построить диаграмму на панели (TPanel). Уточню, что мне не просто нужно вывести изображение, но и обеспечить его перерисовку при изменении размеров панели и возможность прокрутки, если диаграмма получится длинной.

В VB.NET я делала это следующей процедурой:

Private Sub <имя_процедуры> (...) Handles <имя_панели>.Paint
  Dim <имя1> As Graphics = <имя_панели>.CreateGraphics()
  <имя1>.DrawRectangle(...)         //для примера рисуем прямоугольник
  .....................
End Sub

Прокрутка обеспичивалась благодаря вложению одной панели в другую - не утверждаю, что лучший вариант.

Надеюсь, объяснила понятно. Если не трудно, подскажите, как подобное сделать в Delphi 7. Очень прошу.

0

99

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

0

100

А обязательно делать через TFrame? Чем TPanel не подходит? Дело в том, что я Delphi изучаю около 3 месяцев, по книжкам, я не умею работать с TFrame. Компонент TImage очень похож на то, что мне нужно, но имеет два существенных минуса.

Во-первых, у него нет собственного события onPaint. Правда можно использовать соответствующее событие формы. Не самый лучший вариант, но работает.

Вторая проблема более серьёзная. При изменении размеров компонента TImage размеры области, пригодной для вывода изображения, остаются прежними. Изображение получается обрезанным.

Уже несколько дней бьюсь над этой проблемой, никак не могу решить. Правильно говорят, девушки бывают либо красивыми, либо умными.  :surprise:

0

101

Правильно говорят, девушки бывают либо красивыми, либо умными.

Ох-ох-ох. Сама себя не похвалишь - никто не похвалит.) Тряси Джина - он всё умеет.)

0

102

BlueHairLady написал(а):

Во-первых, у него нет собственного события onPaint.

Ему не нужно такого события.

BlueHairLady написал(а):

Вторая проблема более серьёзная. При изменении размеров компонента TImage размеры области, пригодной для вывода изображения, остаются прежними. Изображение получается обрезанным.

Нужно изменять не только размеры самой области Image, но и Image.Picture.Graphic.Width, Image.Picture.Graphic.Height

BlueHairLady написал(а):

Уже несколько дней бьюсь над этой проблемой, никак не могу решить.

Стучи в аську, помогу.

0

103

Djinn написал(а):

Нужно изменять не только размеры самой области Image, но и Image.Picture.Graphic.Width, Image.Picture.Graphic.Height

Я добавила в обработчик события панели TForm1.Panel2Resize строку

Image2.Picture.Graphic.Height:=Image2.Height;

При запуске приложения компилятор выводит ошибку

Project Project1.exe raised exception class EAccessViolation with message 'Access violation at address 0045B45A in module 'Project1.exe'. Read of address 00000000'. Process stopped. Use Step or Run to continue.

При нажатии кнопки OK программа исправно запускается, только её ещё вручную нужно сделать активной, щёлкнув на появившемся значке панели задач. При изменении размеров окна размеры пробной диаграммы изменяются абсолютно корректно. Почти получилось. Но что за ошибку выводит компилятор и как её устранить?

0

104

BlueHairLady написал(а):

Image2.Picture.Graphic.Height:=Image2.Height;

Graphic сначала создать надо. А вообще наверно тебе будет удобней использовать TPaintBox. Там не нужно использовать Graphic, а рисовать надо через событие OnPaint. Находится на вкладке System.

0

105

Спасибо. TPaintBox - именно то, что мне нужно. Вывела на них основные элементы диаграмм, осталось лишь наложить толстый слой make-up-а. К сожалению обнаружилось, что в Delphi у TPanel нет автопрокрутки.  :'(  Жалко, придётся писать вручную.

А можно ещё вопрос? Можно ли сделать так, чтобы главное меню (TMainMenu) простиралось не от края до края через всю форму, а занимало ровно столько места, сколько составляющие его пункты? Причина в том, что чем длиннее панели диаграмм, тем больше информации они могут отобразить. В Бейсике.NET я так делала. Если, конечно, в Делфи это не слишком сложно, не тот у меня уровень.

Отредактировано BlueHairLady (2008-03-23 06:08:39)

+1

106

BlueHairLady написал(а):

К сожалению обнаружилось, что в Delphi у TPanel нет автопрокрутки.  :'(  Жалко, придётся писать вручную.

Не нужно писать в ручную. Frame создаётся так же как обычная форма. New->Frame. Потом из палитры компонентов выбираешь TFrame и ставишь её на форму как TPanel, там появится список, в котором нужно выбрать созданный Frame.

BlueHairLady написал(а):

А можно ещё вопрос? Можно ли сделать так, чтобы главное меню (TMainMenu) простиралось не от края до края через всю форму, а занимало ровно столько места, сколько составляющие его пункты? Причина в том, что чем длиннее панели диаграмм, тем больше информации они могут отобразить. В Бейсике.NET я так делала. Если, конечно, в Делфи это не слишком сложно, не тот у меня уровень.

Вообще-то во всех программах главное меню простирается от края до края, где ты видела по-другому?

0

107

Djinn написал(а):

Вообще-то во всех программах главное меню простирается от края до края, где ты видела по-другому?

В VB.NET (VS 2005), там можно настроить компонент главного меню таким образом. Результат можно посмотреть на примере той же самой Поганки (http://user.rol.ru/~bhlady/programs/vp.htm).

0

108

Вот это да, первый раз такое вижу 8)
Стандартных компонентов для этого в Delphi нет. Есть что-то подобное в наборе компонентов Toolbar2000, там это делается через тулбар. Но вес приложения от использования этих компонентов очень сильно увеличивается.
http://magicteam.emu-land.net/files/menutest.png

0

109

Djinn написал(а):

Есть что-то подобное в наборе компонентов Toolbar2000, там это делается через тулбар.

Разборки в баре - это не для меня.

Djinn написал(а):

Не нужно писать в ручную. Frame создаётся так же как обычная форма. New->Frame. Потом из палитры компонентов выбираешь TFrame и ставишь её на форму как TPanel, там появится список, в котором нужно выбрать созданный Frame.

Увы, фрейм нельзя настрить так, чтобы он выглядел как панель. Можно, конечно, прицепить к форме панель, к панели фрейм, а на фрейм TPaintBox, но легче самой написать прокрутку, чем разбираться в подобном винегрете. Что, кстати, я уже сделала. Диаграммы полностью работают, спасибо за помощь. Правда изрядно косят, нужно делать попиксельную настройку.

0

110

BlueHairLady написал(а):

Увы, фрейм нельзя настрить так, чтобы он выглядел как панель. Можно, конечно, прицепить к форме панель, к панели фрейм, а на фрейм TPaintBox

Так обычно и делается, ничего в этом замудрёного нет.

0

111

Первая программа почти готова, осталось лишь пошлифовать. Не подскажите, трудно ли исправить один нюанс? В Pakostnickе Guyverа (http://guyverperevod.narod.ru/program.html) я обнаружила крайне полезную и нужную в подобных программах штучку: при щелчке на одной-единственной кнопке программа запускает ROM через внешний эмулятор. Естественно, я сразу захотела сделать подобное. Я ничего в таких вещах не понимаю, но с моему счастью, чуть выше по форуму есть соответствующая команда, которую я слепо скопировала в свою программу.

procedure TForm1.Button1Click(Sender: TObject);
begin
  if ShellExecute(0, nil, PChar(strEmul), PChar(strFile), nil, SW_NORMAL)<=32 then ShowMessage('Ошибка при запуске программы);

  //где strEmul и strFile - глобальные строковые переменные, содержащие полное имя эмулятора и файла
end;

Как говорится, пока умные обсуждают, глупые копируют. Нагло и бездумно. :( Всё вроде бы работает, но есть загвоздка.
Во-первых, если запущенное внешнее приложение свёрнуто, то при щелчке на соответствующей кнопке оно так свёрнутым и остаётся.
Во-вторых, если внешняя программа разрешает запускать несколько своих копий, то при каждом щелчке на кнопку создаётся новое окно данного внешнего приложения (к примеру, блокнота).
Скажите, это трудно исправить? Учитывая мои крайне поверхностные знания.

0

112

BlueHairLady написал(а):

Во-первых, если запущенное внешнее приложение свёрнуто, то при щелчке на соответствующей кнопке оно так свёрнутым и остаётся.
Во-вторых, если внешняя программа разрешает запускать несколько своих копий, то при каждом щелчке на кнопку создаётся новое окно данного внешнего приложения (к примеру, блокнота).
Скажите, это трудно исправить? Учитывая мои крайне поверхностные знания.

Только программы, в которых запрограммировано, чтобы их копии не открывались, не будут открываться. А остальные всегда будут открываться повторно.
Кстати вызов с полным списком параметров:
ShellExecute(Application.Handle, PChar('Open'), PChar(ProgName), PChar(ProgParams), PChar(WorkingDir), SW_SHOWNORMAL);

0

113

Решила заскочить, показать, что получилось: http://user.rol.ru/~bhlady/programs/vs.htm . Думаю, что готовая программа - это логичное завершение череды вопросов. Плюсик добавить не получается, но за содействие спасибо.

0

114

О, так это для сравнения файлов как в Total Commander. Очень мило. Молодец.

0

115

Туда бы ещё декомпилятор для сравнения кода :-D

0

116

Это первая из задуманных программ. Сейчас есть мысль заняться усовершенствованием Поганки. Вот только сначала ещё немножко пошлифую интерфейс созданной  Сравнилки: нужно сделать внутрипрограммные процессы более понятными для постороннего человека.

Отредактировано BlueHairLady (2008-04-07 01:34:05)

0

117

Кстати, а насчёт сравнилки кода - а это идея! Например, берёшь деджапанизацию какой-нибудь игрухи, и смотришь, где что переводчег накодил, где что изменил...

0

118

HoRRoR
Можно и в тотал командере понять, какой код где менялся.
А для твоей идеи надо, чтобы программа дизассемблировала машинный код любых платформ.

0

119

Ну почему же для любой? Можно и плагины катать :)
Не, ну представь себе такую прелесть: нажимаешь кнопочку, и тебе сравнивается код, причём "умным" сравнением (как в тотале строки, только ещё с учётом всевозможных nop и т.п.) :)

0

120

Сравнилку подправила, надеюсь, стало понятнее. Но это, конечно, уже не новость, ШЕДЕВР посещают все.

А можно вопрос на немного отвлечённую тему? При создании обновления никак не могла определиться, каким шрифтом писать номера участков на диаграммах. Для качественного отображения цифр шрифт должен был обладать парой особенностей, стандартные, даже уменьшенные, подходили плохо. Мои терзания закончились написанием маленькой сверхпростенькой программки "под себя". Принцип примитивен: вводишь некоторую фразу, выбираешь размер шрифта и сразу на одном экране видишь 49 вариантов написания этих символов. Т.е. всеми шрифтами, которые Delphi считает стандартными. Вместе с тем пространством, которое очищается при выводе букв. Размер шрифтов можно изменить одной клавишей клавиатуры в реальном времени. Моя проблема быстро решилась. Мне это показалось очень удобным и я бы хотела на будущее добавить в эту программку ещё 4 флажка: "полужирный", "курсив", "подчёркнутый", "перечёркнутый". Объяснения, думаю, не нужны. Проблема в том, что мне известен только групповой способ изменения начертания шрифта:

Form1.Canvas.Font.Style := [<список>];

Скажите, а можно одной командой включить/отключить, к примеру, курсив отдельно от трёх остальных стилей?

0


Вы здесь » Magic Team » Программирование » Delphi