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

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

Автор: Maks150988
Дата сообщения: 21.01.2012 13:38
wasilissk
В клиентском приложении структуры те же, что и в модуле. =) Я вот только не понял, а зачем CoInitialize/CoUninitialize функции. Я же OLE не использую. =)
Frodo_Torbins
Блин, неожиданно помогло. =)
Автор: wasilissk
Дата сообщения: 22.01.2012 12:26
Maks150988

Цитата:
Я вот только не понял,

Это не к вам было обращено, я же ник там указал к кому обращаюсь.
Автор: Maks150988
Дата сообщения: 23.01.2012 01:42
wasilissk
Извиняюсь, совсем погряз в коде программы, что уже не замечаю таких очевидностей. =))
Автор: delover
Дата сообщения: 25.01.2012 07:23
wasilissk
Попробовал тру финали, очень жаль что не помогло. Выяснилась особенность немного странная, на некоторых компах закрывается корректно. Просто программа умеет работать ещё и с другими драйверами и возможно где эти драйвера не установлены там она и работает корректно. А вот потом я даже убрал CoInitialize, мой драйвер работает корректно, но так же подвисает прога. Дело не в CoInitialize.
Автор: Maks150988
Дата сообщения: 29.01.2012 11:15
А кто подскажет насчет правильного написания кода к условию.


Код: if (pcp.bHover and pcp.bPressed) then
begin
clrTop := RGB($D3, $F9, $FF);
clrBott := RGB($E0, $EF, $FF);
end
else
if (pcp.bHover and (not pcp.bPressed)) then
begin
clrTop := RGB($D2, $E8, $FE);
clrBott := RGB($C3, $D8, $EC);
end
else
if ((not pcp.bHover) and pcp.bPressed) then
begin
clrTop := RGB($D2, $E8, $FE);
clrBott := RGB($C3, $D8, $EC);
end;
if (pcp.bHover or pcp.bPressed) then
GradFillRect(pcp.hdcMem, pcp.rcClient, clrTop, clrBott, GRADIENT_FILL_RECT_V);
Автор: Frodo_Torbins
Дата сообщения: 29.01.2012 13:25
Maks150988
Компилятор волнуется, что возможна ситуация, когда pcp.bHover и pcp.bPressed false. Как вариант: уберите последний if ((not pcp.bHover... оставив только его begin/end.
Автор: salexn1
Дата сообщения: 30.01.2012 10:37
Maks150988
либо как вариант изначально инициализируй переменные.
Автор: idiMAN
Дата сообщения: 01.02.2012 09:20
Maks150988
Твой код можно переписать так (если конечно в случае pcp.bHover=false и pcp.bPressed=false у тебя не предусмотрен другой цвет):

Код:
clrTop := RGB($D2, $E8, $FE);
clrBott := RGB($C3, $D8, $EC);

if (pcp.bHover and pcp.bPressed) then
begin
clrTop := RGB($D3, $F9, $FF);
clrBott := RGB($E0, $EF, $FF);
end;

if (pcp.bHover or pcp.bPressed) then
GradFillRect(pcp.hdcMem, pcp.rcClient, clrTop, clrBott, GRADIENT_FILL_RECT_V);
Автор: Ichigo2
Дата сообщения: 01.02.2012 13:52
Послали к вам.
Я хочу чтобы моя программа проверяла свою контрольную сумму. Есть процедура MD5File, но если подсунуть ей уже запущенную программу, то будет ошибка. Как правильно это реализовать?
Автор: wasilissk
Дата сообщения: 01.02.2012 14:12
Ichigo2
Использовать процедуру MD5FileEx, которая не вызывает ошибок.
Автор: ant0ni02004
Дата сообщения: 01.02.2012 16:43
salexn1
Maks150988


Цитата:
либо как вариант изначально инициализируй переменные


пару раз хохма случалась, когда после начального присваивания
начиналось "value assigned to ... never used", а без него "переменные не инициализируются"
Автор: HekTo
Дата сообщения: 02.02.2012 10:11
(del)
Автор: king_stiven
Дата сообщения: 03.02.2012 19:31
Собственно моя задача - это посылать в окно bat файла нажатия клавиш, причём окно может быть свёрнутым или скрытым, нашёл вот такую штуку:
http://sources.ru/delphi/delphi_send_keystrokes.shtml

Код:

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

Автор: Gert v.d. Venis

Скачайте компонент Sendkeys
http://sources.ru/delphi/sendkeys.zip


Описание:
Данный компонент получает хэндл(handle) любого запущенного окна и даёт возможность отправить по указанному хэндлу любые комбинации нажатия клавиш.

Совместимость: Все версии Delphi

Собственно сам исходничек:

После того, как проинсталируете этот компонент, создайте новое приложение и поместите на форму кнопку и сам компонент SendKeys. Добавьте следующий код в обработчик события OnClick кнопки:

procedure TForm1.Button1Click(Sender: TObject);
begin
// Запускаем Notepad, и ему мы будем посылать нажатия клавиш
WinExec('NotePad.exe', SW_SHOW);
// В параметре процедуры GetWindowHandle помещаем
// текст заголовка окна Notepad'а.
SendKeys1.GetWindowHandle('Untitled - Notepad');
// Если хэндл окна получен успешно, то отправляем ему текст
if SendKeys1.WindowHandle <> 0 then
SendKeys1.SendKeys('This is a test');
// Так же можно отправить код любой кнопки типа
// RETURN, используя следующий код:
// SendKeys1.SendKeys(Chr(13));
end;

Автор: Ichigo2
Дата сообщения: 03.02.2012 21:45
Чем отличается подключение модулей в секции interface от подключения их в секции implementation?
Автор: Frodo_Torbins
Дата сообщения: 03.02.2012 22:01
king_stiven
Если кроме батников ничего не понимаете, то может вам поможет xStarter или HiAsm?
Что касается компиляторов, то вам нужно скачать отсюда и установить Delphi7. Потом либо скачать отсюда DRKB 3.0 и прочитать там про имитацию нажатий клавиш без всяких сторонних компонентов, либо прочитать про установку компонент без dpk-файлов. Даже и не знаю что легче.

Ichigo2
У каждого модуля могуть быть секции инициализации (initialization) и финализации (finalization). Они выполняются в самом начале и самом конце работы приложения. Обычно туда вставляют код, необходимый для нормальной работы модуля. Так вот секции инициализации всех модулей из раздела interface гарантированно выполнятся до начала работы секции инициализации вашего модуля. Таким образом вы можете спокойно вызывать из них любой код. Для модулей из раздела implementation никаких гарантий нету, поэтому их код нельзя использовать в своей секции инициализации.
Автор: ESV1987
Дата сообщения: 03.02.2012 22:39
Здравствуйте!

Давно пишу простенькие проги на Делфи, читал много руководств, но с некоторыми (кажется, очень простыми) вещами до сих пор от случая к случаю возникают проблемы.

Сейчас вот, к примеру, мучают динамические массивы. Без них не удаётся добиться универсальности создаваемых подпрограмм.

1. Передача динамического массива на вход процедуры и соответственно выдача на выходе другого динамического массива.

На фортране это дело решается элементарно, на вход идёт просто переменная, а в секции описания она описана, как dimension :: XYZ (Ndim) (......). В делфи же создаю я тип type DynAr = array of extended или даже array of array of extended, переменная на входе и выходе процедуры описывается этим типом.

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

Не могли бы вы раз и навсегда мне разъяснить, как мне заслать динамический массив на вход процедуры и внутри процедуры его адекватно обработать, затем выдав другой массив на выходе? Где надо передать указатели и т.п.?

2. Запись большого кол-ва информации в динамический массив.

Так необходимо в программе, чтобы раз в N шагов сохранялась информация в динамический массив. И если шаг очень маленький, то даже на интервале средней длины, часто динамические массивы "переполняются".
Можно ли как-то их описать по особому, чтобы переполнений не было, может не стандартный класс использовать, а библиотеку какую-нибудь.

Мне однажды предложили писать в поток (Stream), но из него неудобно потом считывать. Через анализ содержания не найти нужную строку, приходится запоминать шаги (для считывания по числу байт), что не подходит мне в данном случае.

3. Как узнать все размерности многомерного массива? к примеру у меня массив двумерный, length выдаёт только одну границу, а как узнать вторую? (кроме использования библиотек, где под динамические массивы создан класс, хранящий свойства размерностей, естественно)

Ну вот пока всё, хотя вопросов тьма.

Казалось бы, тема динамических массивов должна быть один раз хорошо освещена в учебниках и всё. А я сколько их не читал, чётких ответов на эти вопросы так и не нашёл. В DRKB предлагают свой класс массивов, но это не всегда удобно..
Автор: akaGM
Дата сообщения: 03.02.2012 23:49
ESV1987

Цитата:
Не могли бы вы раз и навсегда мне разъяснить, как мне заслать динамический массив на вход процедуры и внутри процедуры его адекватно обработать, затем выдав другой массив на выходе? Где надо передать указатели и т.п.?
например, вот так:
Код:
const
N = 5;
var
x, y: array of double;
i: integer;

procedure calc1(N: integer; var x, y: array of double);
var
i: integer;
begin
for i := 0 to N-1 do
y[i] := 10*x[i];
end;

//можно и не передавать размерность и воспользоваться псевдофункциями Low/High
procedure calc2(var x, y: array of double);
var
i: integer;
begin
for i := Low(x) to High(x) do
y[i] := 100*x[i];
end;


begin
//это выделение памяти для x y
setlength(x, N);
setlength(y, N);

for i := 0 to N-1 do
x[i] := i+1;

calc1(N, x, y);
for i := 0 to N-1 do
writeln(i:3, ' ', y[i]);

calc2(x, y);
for i := Low(y) to High(y) do
writeln(i:3, ' ', y[i]);

end.
Автор: Frodo_Torbins
Дата сообщения: 04.02.2012 08:57
ESV1987
Вы напросились Сейчас я буду бомбардировать ваш мозг сильно сложными вещами:
Для начала стоит узнать, как массивы устроены внутри. Вот статья: http://www.transl-gunsmoker.ru/2009/09/blog-post.html По идее вам нужен только раздел "Ссылки (References)", но лучше прочтите всю.
Далее про передачу массивов в подпрограммы: http://www.transl-gunsmoker.ru/2009/09/of-const.html
По поводу специализированных классов: в Delphi2009 и выше есть так называемые дженерики: http://keeper89.blogspot.com/2011/07/delphi.html Я думаю, что они очень сильно могли бы упростить вам жизнь. Если последние версии делфи вам не доступны по причине платности, то можно заменить их свободным Lazarusом.
Автор: ESV1987
Дата сообщения: 04.02.2012 09:23
akaGM

1. Если честно, я так и делал, возможно, только перед входным динамическим массивом, который в процедуре не меняется, я не ставил var, а ставил его только перед выходным.

(... x: array of double, var y: array of double ...);

Проверю на буднях, но по-моему были с таким подходом какие-то проблемы.

2. Это я понимаю, что можно на каждом шаге увеличивать размерность. Но когда массив очень огромный делфи может выдавать сообщение о переполнении памяти (по-моему "out of memory")...


Frodo_Torbins
Спасибо! Буду читать, позже отпишусь, что получилось.
Автор: Frodo_Torbins
Дата сообщения: 04.02.2012 09:52
ESV1987
Перед параметром в функции можно не указывать ничего, указывать const или var. Если не указано ничего, то это передача по значению - каждый раз перед вызовом функции массив будет копироваться. Если указан const или var, то это передача по ссылке. То есть никакого копирования данных не произойдет. Единственная разница между const и var в том, что в случае с const компилятор не позволит вам менять переданное значение. В более новых версиях делфи можно еще использовать out, он аналогичен var, но компилятор запрещает читать из него значения.
Отсюда вывод: если работаете с большими массивами, то нужно использовать const для входных параметров, и var для выходных.
Теперь по поводу увеличения размерности. Проблемы тут возникают в большей степени из-за фрагментации памяти. Проблема фрагментации решается очень просто: нужно увеличивать размер массива не на одну единицу, а сразу на 100, и в отдельной переменной хранить сколько реально используется. Можно делать это самому, а можно поручить дженерику TList<T> или менеджеру памяти FastMM4. Последний кстати работает и в старых делфях, а в новых вообще используется по умолчанию.
Автор: akaGM
Дата сообщения: 04.02.2012 11:06
ESV1987

Цитата:
Но когда массив очень огромный делфи может выдавать сообщение о переполнении памяти (по-моему "out of memory")...
огромный -- это сколько, терабайты?
может тогда надо пересматривать логику программы?
ну или тупо сбрасывать уже посчитанное на диск, и высвобождать память под новую порцию счёта?

и я бы не лез в новомодные языковые расширения типа дженериков без уверенного владения базовыми основами...
Автор: ESV1987
Дата сообщения: 11.02.2012 20:53
у меня кстати ещё один вопрос вспомнился:
Допустим у нас есть несколько однотипных записей (record), у каждой из которых есть поле T:double; Так вот, если написать:

with rec1, rec2, rec3, rec4, rec5, rec6 do T:=198888;

Поле T почему-то меняется только у одной записи (по-моему, первой, но точно я сейчас не скажу). В чём тут проблема?
Автор: Frodo_Torbins
Дата сообщения: 11.02.2012 21:46
ESV1987
Проблема в том, что вы плохо знаете как работает оператор with Если вам нужно поменять одно поле у нескольких записей, то нужно организовать из них массив, и пройтись по нему циклом.
Автор: jr13ster
Дата сообщения: 12.02.2012 00:41
История такая. Имеется некоторый старый агрегат который в процессе своей работы распечатывал на принтере пошаговый рапорт (время начала/конца, номинальные/фактические значения, сообщения об ошибках и т.п.). Принтер накрылся. Совсем. Ремонту не подлежит. К кабелю принтера был подключен компьютер и на скорую руку написана программа, которая выводит рапорт на экран. Программа работает, но есть одно но...Шрифт которым она пишет очень мелкий (размер 8). Можно изменить размер, есть диалог выбора, но он почему-то не срабатывает. Кто в теме, поправьте код пожайлуста. Сам я в Delphi полный ноль, так юзер только. Выкладываю папку целиком, так как программа(ExCom.exe) запускается из неё и в ней ещё есть файлы х.з. имеющие отношение к ней или нет. Сделал скрин на нём всё видно. Папка с программой
Автор: akaGM
Дата сообщения: 12.02.2012 03:13
jr13ster
в архиве не всё...
например, там не хватает библиотек, начинающихся с Adxxx (AdPort) и других, так что не скомпилировать...

но ты попробуй вот что сделать:
в файле ExCom0.pas в самом его конце найди след. блок

Код: procedure TOsnova.Fontdialog2Click(Sender: TObject);
begin
if fontdialog1.execute then
begin
1 //memo1.Font.Name:=fontdialog1.Font.Name;
2 // memo1.Font.Name:='arial';
3 //memo1.Font.Size:=fontdialog1.Font.Size;
end;
end;
Автор: Frodo_Torbins
Дата сообщения: 12.02.2012 09:54
jr13ster
Предлагаю пока обходной вариант: Панель управления -> Экран -> 125% (можно 150%).
Автор: jr13ster
Дата сообщения: 12.02.2012 11:39
akaGM
Большое спасибо за быстрый ответ. Буду на работе только в среду. Объязательно попробую ваше решение. О результате отпишу.

Frodo_Torbins
Спасибо. Такое решение не подходит даже временно, т.к. на компьютере запущены две программы (не указал об этом ранее), одна из них - ExCom - и обе выводят информацию на экран одновременно, каждая в своей половине. Изменения затронут оба окна на экране, что недопустимо.
Автор: Frodo_Torbins
Дата сообщения: 12.02.2012 11:54
jr13ster
Тогда пробуйте так: Reader.rar. Только я сразу предупреждаю, что не имею ни малейшего понятия как оно будет работать, и будет ли вообще, т к используется другая версия компонент для работы с COM-портом.
Автор: akaGM
Дата сообщения: 12.02.2012 12:34
jr13ster,
Frodo_Torbins
ну не знаю...
я не такой специалист в дельфях как вы, но мне кажется, что на все теже 125% (можно 150%), кот. вы предлагаете -- прав я, так как используемый сейчас в программе выбор фонта _не делает ни хрена_ чтобы при этом ни выбиралось...
Автор: Frodo_Torbins
Дата сообщения: 12.02.2012 12:56
akaGM
Да, не делал. Но если программу нельзя было бы перекомпилировать, то такой вариант тоже мог прокатить. Там ведь стояло "memo1.Font.size:= 8", так вот оно конвертируется в высоту в пикселях с учетом DPI. А DPI как раз и настраивается этим "Панель управления -> Экран -> 125%". То есть с помощью этой настройки можно было бы увеличить шрифт в этой проге, попутно увеличив шрифт во всей системе. Вот только jr13ster уже написал, что такой вариант ему не подходит.

Страницы: 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374

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


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