Magic Team

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

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


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


Delphi

Сообщений 61 страница 90 из 149

61

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

Как вариант, вместо удаления, нужно изменять цвет текста в поле ввода на любой другой. Например на красный. Или можно найти подходящий в палитре системных цветов. От первой бочины такой метод не избавляет, зато избавляет от второй.

Если воспользоваться обработкой исключений, то можно избавиться и от первой бочины. Чем тебе не нравится конструкция try?

0

62

Чем тебе не нравится конструкция try?

Пока в ней не разобрался =)

0

63

2 Lain_13: Раздуваешь из мухи слона:
В этом методе происходит обработка ТОЛЬКО INTEGER, как было выше оговорено: "...когда нужен только integer..."
А до минуса можно чуть-чуть расширить логику и все будет в норме, но по-моему и минус там тоже ни к чему (не по задаче ставишь "бочины").

0

64

нда... насчет интэжэра это й как-то упустил Ж). но минус вероятен Ж). все таки подсвечивать другим цветом логичнее, чем принимать без вариантов... а вдруг там полная отсебятина введена?.. Как то привык если уж решать проблему, то так, что б не возникало новых. Тебя просили ввести чесло? Так и введи число, а если ввел что-то левое, так удали и введи число! А не так вот по странному. Просили число ввел бред. Туда втесалась 1 цифра... ЗНАЧИТ ВВЕЛ ЧИСЛО. Просто нет слов Ж). Чес-слово подход оригинальный, но далеко не всегда приемлемый...

0

65

Делается всё гораздо проще, при нажатии клавиши программа смотрит на номер ключа или введённый символ и проводит анализ: если ключ/символ соответствует кнопке/символу '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-' или '.', то вводится соответствующий символ, если же нет, то символ не вводится/удаляется (в зависимости от способа реализации).

+1

66

Плиз, хелпните мне!!! Мне нужно в роме изменить например цвет героя - я знаю, что он хранится по адресу 39F - и это 16, меняю её на 1A в хекс редакторе - и цвет поменялся...

Как всё это реализовать в делфи??? Как там записать в ром инфу, с помощью каких процедур, какой должен быть тип переменной и т.д. Можете просвятить, если не лень, буду очень признателен... Если можно сделайте исходничек маленький - а то я очень большой тугодум ;о) Это ведь дело 5 минут? П О М О Г И Т Е ! ! !

0

67

Или Var F: File; или Var F: TFileStream;
А так же Var FileName: String; Color: Byte;
Если File, то:

AssignFile(F, FileName);
Reset(F,1);
Seek(F, $39F);
BlockWrite(F, Color, 1);
CloseFile(F);

Если TFileStream, то

F := TFileStream.Create(FileName, fmOpenRead);
F.Position := $39F;
F.Write(Color, 1);
F.Free;

0

68

Я же говорил, что я болбес... Как всегда чего-то не получается... :*(

Создал новый проект, на форме расположил кнопку Button1 и OpenDialog1:

var
  Form1: TForm1;
  FileName :string;
  Color: Byte;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
f: File;
begin
if OpenDialog1.Execute then
   begin
AssignFile(F, FileName);
Reset(F,1);
Color:=10;
Seek(F, $87);
BlockWrite(F, Color, 1);
CloseFile(F);

  end;
end;
end.

При открытии рома процесс тормозится на Seek и пишет "Project raised exception class EInOutError with message 'I/O error 6'. Process stopped. Use Step or Run continue"

Если же пишу так:

procedure TForm1.Button1Click(Sender: TObject);
var
F: TFileStream;
begin
if OpenDialog1.Execute then
   begin
F := TFileStream.Create(FileName, fmOpenRead);
F.Position := $87;
Color:=10;
F.Write(Color, 1);
F.Free;

  end;
end;
end.

то тоже нифига не работает и пишет "Project raised exception class EInOutError with message 'Cannot open file'. Process stopped. Use Step or Run continue"

Где я ошибся - может где-то что-то не дописал? Хелп!

0

69

procedure TForm1.Button1Click(Sender: TObject);
var
f: File;
begin
if OpenDialog1.Execute then
   begin
AssignFile(F, FileName);
Reset(F,1);
Color:=10;
Seek(F, $87);
BlockWrite(F, Color, 1);
CloseFile(F);

  end;
end;
end.
Думаю, ошибка ясна.

0

70

Исправь:

if OpenDialog1.Execute then
   begin
AssignFile(F, FileName);

на:

if OpenDialog1.Execute then
   begin
AssignFile(F, OpenDialog1.FileName);

0

71

УРА!!! СПАСИБО О Г Р О М Н О Е!!! Теперь я смогу делать ВЕЩИ!!! ;о)))))))) Ещё раз спасибо!!! А на "F" и "f" у меня прога не ругается - ей всё равно...

Отредактировано guyver (2007-03-16 20:26:51)

0

72

Ещё вот трабла - задал я переменную-массив:

byteArray : array[1..96] of byte;

И считываю из рома 96 символов начиная с 0090:

procedure TForm1.Button2Click(Sender: TObject);
var
F: File;
begin

if OpenDialog1.Execute then
   begin
AssignFile(F, OpenDialog1.FileName);

Reset(F,1);
Seek(F, $90);

BlockRead(F, byteArray, 96, count);

for i := 1 to count do begin
StringGrid1.Cells[c,v]:= IntToStr(byteArray[i]); - а тут я пытаюсь их вписать в StringGrid1, что-то не получается - IntToStr превращает данные типа 00 08 88 88 88  в  0 8 136 136 136 - я запутался, как происходит считывание по байтам? Это 2 символа получается? Т.е. что бы эти символы занести в StringGrid1 как 0 0 0 8 8 8 8 8 8 8 нужно каждый байт раскладывать на 2 числа? И как это сделать -  никто не знает? Мне нужно в StringGrid занести числа не длиннее 1 символа так, как они выглядят в хекс эдиторе... ХЕЛП!!!

0

73

Конвертируй их встроенной функцией InttoHex(A,Conut) - та же самая InttoStr, но число будет в хекс-формате. A - твоя переменная (или массив), Count - число тетрад (в одном байте 2 тетрады).

0

74

Спасибо - так и сделал (правда пришлось написать самому функцию), работает - но вид данных в StringGrid у меня точно такой же - как в хекс эдиторе 00 08 88 1А 2В, теперь вот сижу и думаю, как сделать так, чтобы число "1А" записать так: "1" в первую ячейку, "А" во вторую и т.д..

Т.е. у меня есть переменая HexFromBin(byteArray[i]) - это число, состоящее из 2 знаков (00, 1А, 3В и т.д.) И теперь мне нужно сделать так, чтобы переменной "х" присваивался 1 знак этой переменной, а "у" - второй знак этой переменной...

Например HexFromBin(byteArray[i]) это 1А

х=1
у=А

Как это реализовать? Никто не знает?

Отредактировано guyver (2007-03-17 15:33:17)

0

75

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

Как это реализовать? Никто не знает?

x=1Ah\16
y=(1Ah\16)*16-1Ah
\ - деление без остатка.

0

76

Спасибо... Я уже "разобрался"... Такого я намутил с простой задачей - сделал 2 функции которые делят хекс число на 2 - левую и правую половину, а потом просто вставлял в стринггрид эти половины... Жуть... Вот что бывает, если программирования не было ни в школе, ни в универе... ;о)))

Всё что хотел - реализовал, сейчас мучаюсь с сохранением обратно в ром...

Значит так: у меня стринггрид и в каждой его ячейке по одному знаку (0..9,А,В,С,D,E,F) И информацию из него нужно в ром обратно записать, т.е. нужно создать массив в котором каждое его число будет состоять из двух чисел из соседних ячеек?

допустим у меня в стринггриде инфа такая:

0 0 1 3 4 А 3 В
4 5 2 С 4 5 2 6
3 6 7 3 С А В А

При сохранении в ром нужно создать массив saveArray : array[1..12] of byte, в котором все числа будут такие: 00 13 4А 3В 45 2С 45 26 36 73 СА ВА

И потом записать это в ром:

...
AssignFile(F, SaveDialog1.FileName);

Reset(F,1);
Seek(F, $87); //нужное место в роме
BlockWrite(F, saveArray, 1);
CloseFile(F);
end;
end;

Так вот - вся беда в том, что я не могу получить этот массив из стринггрида (не согласуются у меня byte и string) - помогите с этим для меня непростым делом, умоляю!!! Я вообще слабо представляю - если тип byte то вообще в каком виде информация пишется в ром? Совсем я запутался с переводом чисел из одной системы счисления в другую... К какому виду приводить числа перед их записью в ром???

Отредактировано guyver (2007-03-18 02:41:20)

0

77

Ну помогите же кто-нибудь!!! Я уже сделал свой редактор уровней - всё в нём работает кроме сохранения!!! :*(

0

78

Присвоить ноль какой-нибудь переменной J. Считывать каждый элемент стринггрида в цикле и записывать их в массив.
C: Char - это у нас будет считанный элемент.
B: Byte - байт, в который бум записывать коды
I: Integer - это у нас будет индекс массива
..... //это внутри цикла
If Odd(J) then //Если J нечётная (J = 1,3,5 и т.д.)
begin
B := B + (HexToInt(C) shl 4); //добавляем к нашему байту следующее число
saveArray[i] := B; //записываем байт в savearray
Inc(I); //Увеличиваем индекс массива
end Else B := HexToInt(C); //Присваиваем к нашему байту считанное из стринггрида число
Inc(J); //Увеличиваем J

Последний параметр BlockWrite - это кол-во байт, которые нужно записать, так что вот так:
BlockWrite(F, saveArray, 12);
или вот так:
BlockWrite(F, saveArray, SizeOf(saveArray));

0

79

Спасибо огромное всем, кто мне помогал!!! Я уже сделал прогу - и хоть код в ней - просто ужас (то что у Djinn'а влезло в 3 строчки - у меня влезло в 30), и весит эта простенькая прога около 700 кБ (очень огромная получилась...) но она работает!!! Вот так делая редактор уровней для дендевской игрушки я написал и хекс-редактор (как всегда хотел сделать одно, а получилось совсем другое ;о))))))

0

80

Привет ещё раз, о крутые программеры!!! У меня опять вопрос - сделал я свою прогу, работает - косяков нет... Но в ней есть один БОЛЬШОЙ минус - скорость работы программы зависит от разрешения экрана... Например если у меня стоит разрешение 600*800, то прога просто летает - работает мгновенно! А если оно 1280*960, то прога жууууууууууутко тормозит - пока обновятся все картинки в стринггриде - проходит целая вечность... В связи с этим вопрос - а как ещё можно отображать картинки, в каком элементе? Как я понимаю у меня тормоза потому, что stringgrid ПОСТОЯННО обновляет картинки - т.е. даже если изменилась всего одна, то он их все обновляет... И вообще он это делает не только при загрузке картинок в ячейки, а постоянно... Как быть? Какой компонент использовать? Хелп!!!

0

81

Оптимизировать отрисовку картинок.

0

82

Думаю, дело не в скорости отрисовки а в постоянной отрисовке как таковой =) Надо разобраться, почему постоянно генерируется, скажем, StringGridDrawCell и производить отрисовку только на OnCreate.
PS:Кстати, это ты про Wrecking Crew Editor?

0

83

Ага... Я уже думал DrawGrid использовать, но это то же самое, что и StringGrid - тоже постоянная отрисовка... Сижу вот задаю непостоянную отрисовку - прога стала работать просто замечательно - быстро! Теперь отрисовываю только 1 клетку в гриде, ту которая поменялась, а не весь грид как раньше... НО опять 1 косяк - если её свернуть, а потом развернуть - тут и начинается весь прикол... Происходит ЖЖЖЖУУУУУУУУУУткая отрисовка, просто МОНСТРИЧЕСКАЯ... А иногда вообще изображение пропадает... Сижу думаю что делать ;о) Надеюсь выйдет что-нибудь ;о))))))

Отредактировано guyver (2007-05-03 18:01:06)

0

84

Попробуй использовать DelphiX, а вместо Grid контролируй координаты.

0

85

Рисовать картинки в StringGrid - это жесть.

0

86

Понятно что жесть - просто я с другими компонентами мало знаком, да и ещё хотелось сделать прогу на стандартных компонентах, чтобы ничего не устанавливать ;о)

0

87

TImage - стандартный компонент. На нём всё что угодно нарисовать можно.

0

88

Вот ещё вопрос:

В своей программе (сильно сказано!) я читаю ром так:

procedure TForm1.BitBtn1Click(Sender: TObject);
var
Result1: String;
S, Minus: integer;
F: File;
byteArray : array[1..2] of byte;
count  : Integer;
begin
Result1 := '' ; S:=0; Minus :=0;

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

Seek(F, S);
while not EOF(F)  do begin
BlockRead(F, byteArray, 1, count); //читаем файл по 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;

   end;
CloseFile(F); // Закрываем файл
end;

Вот такой ужасный код - вроде он работает ;о))) С Ромами весом до 1 Мб проблем нет - но вот если файл весит 30-40 Мб, то программа работает Очень медленно... Всвязи с этим вопрос - я читаю символ из файла, потом проверяю есть ли он в моей таблице перекодировки, если есть - добавляю его в результат, проверяю следующий символ... Если он есть в таблице - добавляю его в результат, если нет его в таблице - печатаю результат, обнуляю результат и перехожу к следующему символу... А если я сначала открою весь файл, а потом уже буду выполнять операции над символами - будет ли от этого выигрыш во времени? Вообще как оптимизировать этот процесс? Как сделать его быстрее?

0

89

C потоками работать?...

+1

90

Эх, если бы знать что это такое ;о) Пойду смотреть... Знать бы ещё где смотреть ;о)))

Загружал весь файл сразу, а потом уже проводил операции над символами - на скорость это никак не повлияло - так и осталась меееееееееедленной ;О))) Покперевод раз в 50-100 быстрее работает - а результат тот же что и у меня, но скорость...

Как я понимаю сложность работы с потоками - это сведение конечного результата... Ну типа 1 поток прошерстил 1000 символов, а предложение оборвалось на середине, 2 поток начнёт шерстить свои 1000 символов с середины предложения... Т.е. могут "выпасть" определённые слова при вынимании текста?В инете пока ничего полезного не нашёл, т.к. трудно искать то, о чём даже не представляешь ;о)))

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

0


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