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

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

Автор: Jokerjar79
Дата сообщения: 01.01.2008 17:47
Erazer, скорей всего, нужны прототипы функции. Есть, допустим, в модуле функция somefunc, берешь ее прототип (имя, входные и выходные параметры) и прописываешь до ключевого слова implementation. Попробуй
Автор: ymg2000
Дата сообщения: 01.01.2008 19:33
Erazer
Лучше приведи фрагмент кода - тогда проще будет разобраться с областью видимости. А так непонятно: ты не видишь процедуры или методы класса.
Автор: vladk1973
Дата сообщения: 01.01.2008 19:59
Erazer
Методы класса видны в другом модуле, если они обьявлены в секции не ниже public в описании класса
Для потомков класса также видны методы из секции protected
Автор: OdesitVadim
Дата сообщения: 01.01.2008 21:11
Maks150988

Цитата:
необходима функция Format

Можно использовать wsprintf - она экспортируется с системных длл. кода должно добавить немного. Читать здесь http://www.delphikingdom.com/asp/viewitem.asp?catalogid=586.
Также почитайте комментарии к статье
Автор: Maks150988
Дата сообщения: 02.01.2008 01:42
Такс возник еще один вопрос. Использую трекбар и работаю с контролами на одном вин апи. Решил сделать примерчик для применения прозрачности окна программы путем перемещения трекбара. Все бы ничего, да вот когда трекбар становится в начальное нулевое значение, окно не ставится полностью прозрачным. Там прозрачность где-то 150. Далее код и ресурс. А то аттачи сюда нельзя прикладывать, поэтому текст...

[more=Читать дальше..]


Код:
program Transparent;

uses
Windows, Messages, CommCtrl;

{$R Transparent.RES}

const
RES_DLG_MAIN = 101;
IDC_DLG_TRCK = 1001;
IDC_DLG_EDIT = 1002;

function MainDlgProc(hWnd : HWND; Msg, WParam : Word; LParam : Longint) : BOOL; stdcall;
const
cUseAlpha : array [Boolean] of Integer = (0, LWA_ALPHA);
cUseColorKey : array [Boolean] of Integer = (0, LWA_COLORKEY);
var
AStyle, VolInt : Integer;
VolStr : array [0..15] of Char;
begin
case Msg of
WM_INITDIALOG :
begin
SendMessage(GetDlgItem(hWnd, IDC_DLG_TRCK), TBM_SETRANGE, Integer(TRUE), MAKELONG(0, 255)); // Bereich setzen
SendMessage(GetDlgItem(hWnd, IDC_DLG_TRCK), TBM_SETPOS, Integer(TRUE), 255); // aktuelle Position setzen
SendMessage(GetDlgItem(hWnd, IDC_DLG_TRCK), TBM_SETTICFREQ, 20, 0); { erfordert TBS_AUTOTICKS }
SendMessage(GetDlgItem(hWnd, IDC_DLG_TRCK), TBM_SETLINESIZE, 0, 5); // Schrittweite fьr die Pfeiltasten
SendMessage(GetDlgItem(hWnd, IDC_DLG_TRCK), TBM_SETPAGESIZE, 0, 10);
AStyle := GetWindowLong(hWnd, GWL_EXSTYLE);
if (AStyle and WS_EX_LAYERED) = 0 then
SetWindowLong(hWnd, GWL_EXSTYLE, AStyle or WS_EX_LAYERED);
SetLayeredWindowAttributes(hWnd, 0, Byte(PChar(String(VolInt))), cUseAlpha[True] or cUseColorKey[False]);
SetDlgItemText(hWnd, IDC_DLG_EDIT, '255');
end;
WM_HSCROLL: // wird bei Verдnderung der Slider-Position gesendet
begin
case LoWord(wParam) of // LoWord enthдlt die entsprechenden Benachrichtigungs-Codes
TB_THUMBTRACK, // ziehen des "Sliders"
TB_TOP, // Pos1
TB_BOTTOM, // Ende
TB_LINEUP, // Pfeiltasten links/rechts
TB_LINEDOWN, // Pfeiltasten oben/unten
TB_PAGEDOWN, // Bild runter & in die Leiste geklickt
TB_PAGEUP:
begin
VolInt := Sendmessage(GetDlgItem(hWnd, IDC_DLG_TRCK), TBM_GETPOS, 0, 0);
wvsprintf(VolStr, '%d', PChar(@VolInt));
SetLayeredWindowAttributes(hWnd, 0, Byte(PChar(String(VolInt))), cUseAlpha[True] or cUseColorKey[False]);
SetDlgItemText(hWnd, IDC_DLG_EDIT, PChar(@VolStr));
end;
end;
end;
WM_CLOSE:
begin
PostquitMessage(0);
end;
end;
MainDlgProc := FALSE;
end;

begin
InitCommonControls;
DialogBoxParam(hInstance, PChar(RES_DLG_MAIN), 0, @MainDlgProc, 0);
ExitProcess(hInstance);
end.

Автор: SERGE_BLIZNUK
Дата сообщения: 02.01.2008 08:43
Maks150988

Цитата:
Захотелось как можно меньше сделать код программы и размер исполняемого файла.
Если задача позволяет, рекомендую попробовать KOL and MCK : http://kolnmck.ru/start.shtml или оф.сайт KOL MCK. На этих же сайтах есть статьи, примеры и т.д. Недостаток применения данной технологии состоит в том, что прийдётся ПОЛНОСТЬЮ отказаться от VCL.
Автор: Maks150988
Дата сообщения: 02.01.2008 22:13
SERGE_BLIZNUK да нунафиг этот KOL.

п.с. меня попросили соорудить программку для воспроизведения потокового аудио через bass.dll. вообщем глянул я там пример с ней и надо мне было переделать под вин апи (на vcl было бы попроще).

[more=Читать дальше..]program player;

uses
Windows, Messages, CommDlg, SysUtils, Bass;

{$R player.res}

const
RESOURCE_DIALOG = 101;
STATIC_STATUS = 1002;
BUTTON_PLAY = 1003;
BUTTON_EXIT = 1004;
var
cthread : DWORD = 0;
chan : HSTREAM = 0;
hWin : Integer;

procedure Error(es : String);
begin
MessageBox(hwin, PChar(es + #13#10 + '(error code: ' + IntToStr(BASS_ErrorGetCode) + ')'), nil, 0);
end;

procedure DoMeta(meta : PChar);
var
p : Integer;
begin
if (meta <> nil) then
begin
p := Pos('StreamTitle = ', meta);
if (p = 0) then
Exit;
p := p + 13;
SendMessage(hWin, WM_COMMAND, 7, DWORD(PChar(Copy(meta, p, Pos(';', meta) - p - 1))));
end;
end;

procedure MetaSync(handle : HSYNC; channel, data, user : DWORD); stdcall;
begin
DoMeta(PChar(data));
end;

procedure StatusProc(buffer : Pointer; len, user : DWORD); stdcall;
begin
if (buffer <> nil) and (len = 0) then
SendMessage(hWin, WM_COMMAND, 8, DWORD(PChar(buffer)));
end;

function OpenURL(URL : PChar) : Integer;
var
icy : PChar;
Len, Progress : DWORD;
begin
Result := 0;
BASS_StreamFree(chan); // close old stream
progress := 0;
SendMessage(hwin, WM_COMMAND, 0, 0); // reset the Labels and trying connecting
chan := BASS_StreamCreateURL(url, 0, BASS_STREAM_STATUS, @StatusProc, 0);
if (chan = 0) then
begin
SendMessage(hwin, WM_COMMAND, 1, 0); // Oops Error
end
else
begin
repeat
len := BASS_StreamGetFilePosition(chan, BASS_FILEPOS_END);
if (len = DW_Error) then
break; // something's gone wrong! (eg. BASS_Free called)
progress := (BASS_StreamGetFilePosition(chan, BASS_FILEPOS_DOWNLOAD) -
BASS_StreamGetFilePosition(chan, BASS_FILEPOS_CURRENT)) * 100 div len;
// percentage of buffer filled
SendMessage(hwin, WM_COMMAND, 2, progress); // show the Progess value in the label
until
progress > 75;
// get the broadcast name and bitrate
icy := BASS_ChannelGetTags(chan, BASS_TAG_ICY);
if (icy = nil) then
icy := BASS_ChannelGetTags(chan, BASS_TAG_HTTP); // no ICY tags, try HTTP
if (icy <> nil) then
while (icy^ <> #0) do
begin
if (Copy(icy, 1, 9) = 'icy-name:') then
SendMessage(hwin, WM_COMMAND, 3, DWORD(PChar(Copy(icy, 10, MaxInt))))
else if (Copy(icy, 1, 7) = 'icy-br:') then
SendMessage(hwin, WM_COMMAND, 4, DWORD(PChar('bitrate: ' + Copy(icy, 8, MaxInt))));
icy := icy + Length(icy) + 1;
end;
// get the stream title and set sync for subsequent titles
DoMeta(BASS_ChannelGetTags(chan, BASS_TAG_META));
BASS_ChannelSetSync(chan, BASS_SYNC_META, 0, @MetaSync, 0);
// play it!
BASS_ChannelPlay(chan, FALSE);
end;
cthread := 0;
end;

procedure Playradio;
var
ThreadId: Cardinal;
begin
if (cthread <> 0) then
MessageBeep(0)
else
cthread := BeginThread(nil, 0, @OpenURL, PChar('http://radio-1.avtograd.ru:8001/radio/15'), 0, ThreadId);
end;

function MainDlgProc(hWnd : HWND; uMsg : UINT; wp : WPARAM; lp : LPARAM) : bool; stdcall;
var caption:string; Msg: TMessage;
begin

hwin:=hwnd;
Result := False;
case uMsg of



WM_INITDIALOG : begin

if (HIWORD(BASS_GetVersion) <> BASSVERSION) then
begin
MessageBox(0, 'An incorrect version of BASS.DLL was loaded', nil, MB_ICONERROR);
Halt;
end;
if (not BASS_Init(-1, 44100, 0, hwin, nil)) then
begin
Error('Can''t initialize device');
Halt;
end;
BASS_SetConfig(BASS_CONFIG_NET_PLAYLIST, 1); // enable playlist processing
BASS_SetConfig(BASS_CONFIG_NET_PREBUF, 0); // setup proxy server location

end;
WM_COMMAND : begin
case LoWord(wp) of

BUTTON_PLAY :begin Playradio; bass_start; end;
1 : SetDlgItemText(hwin, STATIC_STATUS, 'huli error?');

0 : SetDlgItemText(hwin, STATIC_STATUS, 'connect');
4 : SetDlgItemText(hwin, STATIC_STATUS, 'not play');
2 : SetDlgItemText(hwin, STATIC_STATUS, pchar(Format('buffering... %d%%', [msg.LParam])));


BUTTON_EXIT : begin BASS_Pause; end;
end;
end;
WM_DESTROY, WM_CLOSE : begin BASS_Free; PostQuitMessage(0); end;
end;
end;

begin
DialogBox(hInstance, PChar(RESOURCE_DIALOG), 0, @MainDlgProc);
end.
[/more]
проблемка в том что я не знаю как переконвертировать число в процентах буферизации - слишком большое оно получается. может в функции format поделить надо или с integer поиграться?
Автор: Chukotka
Дата сообщения: 02.01.2008 23:28
Maks150988
Что-то мне подсказывает, что те, кому
Цитата:
надо переделать под вин апи
редко испытывают затруднения с вопросами типа

Цитата:
я не знаю как переконвертировать число в процентах буферизации

Может все-таки
Цитата:
на vcl было бы попроще

А после того, как все отладите под vcl, можно и на WinAPI пробовать.
Автор: Maks150988
Дата сообщения: 03.01.2008 01:09
Chukotka
да не тут такое дело. я впервые с библиотекой bass работаю. в демо примере там код на vcl. сейчас только понял как надо правильно сделать. только вот проблема при отображении процентов буферизации: слишком сильно мерцает контрол при обновлении, хотя сама информация обновляется раз в секунду. в чем может быть проблема?
Автор: Chukotka
Дата сообщения: 03.01.2008 02:26
Maks150988

Цитата:
слишком сильно мерцает контрол при обновлении, хотя сама информация обновляется раз в секунду

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

Код:
Curr := (BASS_StreamGetFilePosition(chan, BASS_FILEPOS_DOWNLOAD) -
BASS_StreamGetFilePosition(chan, BASS_FILEPOS_CURRENT)) * 100 div len;
// percentage of buffer filled
if (Curr <> Progress) then
begin
progress := Curr;

SendMessage(hwin, WM_COMMAND, 2, progress); // show the Progess value in the label
end;
Автор: Maks150988
Дата сообщения: 03.01.2008 03:33
Chukotka
Спасибо!!! То что нужно.
Автор: Maks150988
Дата сообщения: 03.01.2008 13:05
Возникли еще вопросы:
1. Нужен таймер, отсчитывающий время в секунадх. Надо для отсчета времени воспроизведения потокового аудио. Лучшим вариантом для меня будет SetDlgItemText с результирующим значением в процедуре, которую буду обновлять через WM_TIMER. Посмотрел некоторые реализации таймеров с секундами - там используется FormatDateTime. Хотелось бы чтобы таймер отображал минуты и секунды - ну типа так 00:00
2. В библиотеке BASS есть функция BASS_SetConfig. Так вот там есть таймаут соединения, при котором если ответ от сервера не получен, действия дальнейшие прекращаются. Это BASS_CONFIG_NET_TIMEOUT. У меня другая трабла: некоторые радио вообще не играют, но порт после этого остается открыт, если перейти к другой станции. Если поток нормально открывается и переходить к другой станции, то все нормально - текущий порт закрывается и открывается новый. Тут этого не происходит. Может тут тоже нужно повесить таймер? Смотрел справку к этой библиотеке и там вроде не было такой функции для такого таймаута, а в демо примере фигня и не все возможности задействованы.
Автор: YuRRiX
Дата сообщения: 03.01.2008 17:03
Подскажите алгоритм корректировки CRC32? Есть RAW файл, в котором можно изменить только 16 байт по заданному адресу. Спасибо.
Автор: Chukotka
Дата сообщения: 03.01.2008 17:29
Maks150988

Цитата:
Возникли еще вопросы


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

Вы для начала определитесь, что у вас должен делать таймер. Потом попробуйте сходить на форум на сайте производителя и позадавать вопросы там. Чтение литературы тоже очень помогает. А то создается впечатление, что при возникновении проблемы вы не пытаетесь решить ее самостоятельно, а сразу взываете о помощи.
Автор: YuRRiX
Дата сообщения: 03.01.2008 17:38
Chukotka. 16 байт.
Автор: Chukotka
Дата сообщения: 03.01.2008 17:41
YuRRiX

Цитата:
Подскажите алгоритм корректировки CRC32

А поиск использовать религия запрещает? Хотя бы вот так - гугл выдает примерно 278 страничек.
Автор: YuRRiX
Дата сообщения: 03.01.2008 17:46
Chukotka
Сформируй запрос.
99.9999999999999999% касаются только вычисления. или изменения pe файлов.
Автор: SERGE_BLIZNUK
Дата сообщения: 03.01.2008 18:41
YuRRiX
вот здесь - FAQ по вычислению CRC - faqs_org_ru
посмотрите там ответ [more]
* From : Dmitry Tomashpolski, 2:5030/163.67 (Wed 03 Dec 1997 21:51)
* Subj : CRC-для тех,кто не понял

>> допустим,что есть некий файл (килошников на 100)
>> для него CRC 32 бита причем я его знаю так же мне
>> известен метод получения CRC
Я так понял что задано некое число, под котоpое хочется подогнать файл так,
чтобы после подгонки его CRC стала pава этому заданному числу.
... [/more]
предвидя возможные вопросы, сразу предупреждаю, я в алгоритме восстановления не разбирался ;-)

Автор: Chukotka
Дата сообщения: 03.01.2008 19:06
YuRRiX

Цитата:
Подскажите алгоритм корректировки CRC32

По сути же, вам нужен алгоритм корректировки файла под конкр CRC.
SERGE_BLIZNUK
Спасибо за ссылку, сохранил для себя на будущее - вдруг пригодится.
Автор: Maks150988
Дата сообщения: 03.01.2008 20:16
Chukotka

Цитата:
Вы для начала определитесь, что у вас должен делать таймер. Потом попробуйте сходить на форум на сайте производителя и позадавать вопросы там. Чтение литературы тоже очень помогает. А то создается впечатление, что при возникновении проблемы вы не пытаетесь решить ее самостоятельно, а сразу взываете о помощи.

Да я в поисковиках смотрел. Там ерундень типа как обновить окошко через определенный промежуток времени и т.д. Мне нужно чтобы начинал отсчет таймер и его результат отображался в виде "минуты:секунды". Ну как в часах секундомер есть, вот это и надо. Не знаю как объяснить то еще.
Автор: xy
Дата сообщения: 03.01.2008 20:35
Народ, кто-то сталкиваля с проблемой ввода украинского языка в делфи-приложениях под Вистой :-?
(русский при этом работает, копи-паст украинского тоже - не работает только клавиатурный ввод украинского)

Похоже на неправильную настройку локалей или что-то такое :) под ХР всё нормально..
Заранее спасибо за помощь ;)
Автор: Maks150988
Дата сообщения: 06.01.2008 14:34
Ну неужели здесь никто не может помочь как создать обычный секундомер? Ну не могу найти пример. И не знаю как таковое сделать...
Автор: Frodo_Torbins
Дата сообщения: 06.01.2008 14:35
xy Это проблемы Висты. Нужно поставить специальный хотфикс, который высылают по запросу на почту ( http://support.microsoft.com/kb/936060/en-us ), или подождать sp1.

Maks150988 Есть несколько способов сделать секундомер. Простейший вариант делается в три этапа:
1. Чтобы во время работы секундомера знать сколько уже прошло времени нужно перед его запуском сохранить текущее время в переменную.
2. TDateTime по сути является Double, тоесть простым числовым типом, который хранит количество милисекунд. А значит с ним как с числовым типом можно производить любые арифметические операции. В каждом цикле таймера будем отнимать от текущего времени сохраненное перед запуском. Полученная разница и есть количество прошедшего времени.
3. Осталось все это вывести. Например в лебел. Идеально подходит для этого функция FormatDateTime. Первый параметр у нее - строка определяющая форматирование. Узнать про нее можно в справке, в D7 статья называется "Date-Time Format Strings". Второй параметр наша разница. Впрочем полученный текст можно выводить куда угодно.
Недостаток этого способа очевиден: если во время работы нашего секундомера ктото переведет системное время, он собьется.
Если это критично, можно организовать секундомер по другому:
1. Заводим переменную TDateTime и обнуляем ее.
2. Выставляем фиксированный промежуток работы таймера. Например 100 мс.
3. При каждом срабатывании таймера увеличиваем нашу переменную на указанный промежуток (100 мс).
4. Выводим как и в предыдущем способе.
У этого способа тоже есть недостаток. Если по вине какогото ресурсоемкого приложения наша программа зависнет, то таймер не сработает, и переменная не будет увеличена.

P.S. Если вам не охота в следующий раз читать такой здоровенный трактат, то постарайтесь, прежде чем задавать свой вопрос, потратить чуть больше времени и усилий и всеже найти на него ответ самостоятельно.
Автор: Maks150988
Дата сообщения: 06.01.2008 17:12
Frodo_Torbins
Да никогда я не делал такие таймеры. Максимум SetTimer для какой-то процедуры. Надо полагать FormatDateTime('mm:ss', переменная + 1)? Я затрудняюсь. Киньте хотя бы набросок.
Автор: Frodo_Torbins
Дата сообщения: 06.01.2008 19:01
А вы поэкспериментируйте
Автор: Chukotka
Дата сообщения: 06.01.2008 19:54
Maks150988

Цитата:
Надо полагать FormatDateTime('mm:ss', переменная + 1)?

А почему не сделать усилие и не почитать описание функции в справочной системе Delphi? Не я один вам замечал, что одно дело, когда перед тем, как задавать вопрос, человек пытается решить вопрос самостоятельно, а другое - когда при любом затруднении бежит в форум.
А с таким отношением как у вас, скоро на все вопросы будут отвечать одним словом: rtfm (поищите в инете, что это значит).
Автор: xy
Дата сообщения: 06.01.2008 20:04
Frodo_Torbins
спасибо!
Автор: Maks150988
Дата сообщения: 06.01.2008 22:49
Chukotka
а че бы не помочь вам? почему на каких-то форумах помогают чуть ли не как создать мессаджбокс, а тут не хотят написать долбанный пример с этим FormatDateTime?
открою секрет. мнеу нужен этот таймер для отсчета времени вопроизведения аудио потока в bass. к ней такого примера нихрена нет. кое-как удалось найти исходники подобных плейеров, но там код типа FormatDateTime ('nn:ss', Length / (1000 * 24 * 60 * 60)), где lenght - длина аудио потока. так вот я тут двал свой исходный код. и если подкорректировать мой код под этот, то длина всегда постоянна 02:00. Вот я и подумал что нужно сделать тогда обычный секундомер, но поиском находит десяток одинаковых примеров, где делфийцы показывают как выполнить в определенное время како-то задание по таймеру. делфи я устанавливал без справок, а дистрибутива нет. с выходом в инет проблемы тоже. вот блин попросил помощи называется...
Автор: Chukotka
Дата сообщения: 06.01.2008 23:53
Maks150988

Цитата:
а че бы не помочь вам?

Только хамить не надо. Одно дело, когда просят разобраться в проблеме, а другое - когда человек упорно просит разжевать штатную функцию, полностью описанную в справке. Кроме того, вам Frodo_Torbins полностью разжевал процедуру.

Цитата:
а тут не хотят написать долбанный пример

Научитесь правильно задавать вопросы, тогда не надо будет "открывать секреты". Тут народ в основном доброжелательный, но при одном условии - когда видно, что человек перед тем, как задать вопрос, поработал сам. Вы же беретесь писать на чистом API и заботитесь о том, чтобы "программа не увеличилась на 30Кб" в результате использования дополнительной библиотеки. Может не обманывать себя, установить нормальный дистрибутив, почитать справку и реализовать все в vcl для начала?

PS. Если процедура MetaSync() является calback'ом и периодически вызывается при проигрывании, то тут вообще не нужен таймер. Отображайте время точно так же, как отображали процент скачивания:

Код: var
StartedAt: TDateTime;
const
UpdatedAt: TDateTime = 0;
OneSec = 1 / (60 * 60 * 24);
...
// при старте проигрывания
// play it!
BASS_ChannelPlay(chan, FALSE);
StartedAt := Now;
...
// при обновлении
case LoWord(wp) of
...
7:
begin
if (Now > UpdatedAt) then
begin
UpdatedAt := Now + OneSec;
Text := FormatDateTime('Время проигрывания hh:nn:ss', Now - StartedAt);
end;
end;
Автор: Maks150988
Дата сообщения: 07.01.2008 01:00
Ба, ну наконец-то! Большое спасибо. Как раз вынес все это в отдельную процедурку. После BASS_ChannelPlay(chan, FALSE) прописал ее. И через wm_timer активировал, предварительно прописав в процедуре settimer.
P.S. да не принимайте близко так. Я не хамил. Просто действительно, ну нет у меня возможности найти дистрибутив делфи. Какой есть сейчас без файлов документации.
А искать в поисковиках уже надоело, потому что по большему счету выдавалась информация о запуске события по таймеру.
Ну не привык я работать с таймером. Для меня смутно все.
P.P.S. Я бы не задавал таких вопросов, если бы на VCL весь интерфейс делал. Через сплошной API трудно, но очень интересно и познавательно.
Огромная благодарность.))

Страницы: 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667

Предыдущая тема: 1С: Конвертация данных 2.0


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