![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Совместное использование процедур юнита и компонента [D7]
ProgRAMmer Dimonych © (2006-09-30 22:56:00)Пишу свою замену TMediaPlayer. Кто-нибудь, подскажите, плз, как из процедуры, не являющейся методом TMyMediaPlayer, вызвать метод самого TMyMediaPlayer. Заранее спс.
ProgRAMmer Dimonych (2006-10-01 00:23:00) [1]При добавлении Handle надо что-то добавлять в конструктор (или другой метод) моего TComponent или просто написать
private
FHandle:THandle;
published
Handle:THandle read FHandle;?
guav (2006-10-01 00:02:00) [2]Есть такая возможность.
http://kladovka.net.ru/index.cgi?pid=dir&rid=8&ppn=2здесь найти makeinstance.zip и скачать.
Однако обычно без этого можно обойтись. У waveOutOpen есть параметр dwCallbackInstance куда можно передать Self. в "обычной функции" можно сразу же вызвать соответствц метод и тогда почти весь код будет в классе.
Примеров на эту тему в VCL хватает, хотя бы TThread и ThreadProc.
Сергей М. (2006-09-30 23:56:00) [3]
> waveOutOpen для callback'а метод класса не берёт: ему обычную
> процедуру подавай
Ну так и подай !
К чему вся эта шняга, что ты привел ?
Заметь, что колбэк-ф-ции как правило имеют одним из параметров произвольное пользовательское значение, которое ты волен использовать как твоей душеньке угодно, в дан.случае - для передачи ссылки на свой объект
Джо (2006-09-30 23:47:00) [4]> Просто хочется самому всей этой фигнёй пострадать, а waveOutOpen
> для callback'а метод класса не берёт: ему обычную процедуру
> подавай!
И причем здесь тогда вообще вся тема? Вот и подавай ему обычную процедуру.
ProgRAMmer Dimonych (2006-09-30 23:20:00) [5]Запасаемся валерьянкой...
unit MMPlayer;
interface
uses
SysUtils, Classes, MMSystem;
type
TShortInt=array [0..1] of ShortInt;
PShortInt=^TShortInt;
//
DWord=LongWord;
TMMPlayer = class(TComponent)
private
//Common
FFileName:ANSIString;
//For WAVE
FmtChunk,DataChunk:Int64;
WaveFmt:TWAVEFORMATEX;
WO:HWAVEOUT;
WOState:Boolean;
sndHdr:array [boolean] of TWaveHdr;
sndData:array [boolean] of PShortInt;
sndPlay:Boolean;
CurrPosition:Int64;
//Special
FErrorList:TStringList;
{ Private declarations }
protected
procedure ReLoad;
procedure CheckAndPack(FormatChunk:Int64);
function ReadString(Count:Integer; Stream:TStream):ANSIString;
procedure LookForChunk(ChunkID:ANSIString; Stream:TStream; var Position:Int64);
procedure Close;
procedure Open;
{ Protected declarations }
public
FFile:TMemoryStream;
constructor Create(AOwner:TComponent); override;
destructor Destroy; override;
//
property FileName:ANSIString read FFileName;
property Errors:TStringList read FErrorList;
//
procedure LoadFromFile(FileName:ANSIString);
procedure LoadFromStream(Stream:TStream);
{ Public declarations }
published
{ Published declarations }
end;
procedure Register;
procedure Ready(hW:HWAVEOUT; uMsg,dwInstance,dwParam1,dwParam2:DWord); stdcall;
procedure PlayNext;
implementation
procedure Register;
begin
RegisterComponents('My controls', [TMMPlayer]);
end;
constructor TMMPlayer.Create(AOwner:TComponent);
begin
//Create
inherited Create(AOwner);
//Common
FFile:=TMemoryStream.Create;
//Special
FErrorList:=TStringList.Create;
//
WOState:=False;
end;
destructor TMMPlayer.Destroy;
begin
//
Close;
//Special
FErrorList.Free;
//Common
FFile.Free;
//Destroy
inherited Destroy;
end;
procedure TMMPlayer.LoadFromFile(FileName:ANSIString);
var
Tmp:Integer;
begin
FFileName:=FileName;
FFile.LoadFromFile(FileName);
FErrorList.Add('Loading from the file '+FileName+'...');
Tmp:=FErrorList.Count;
ReLoad;
if Tmp=FErrorList.Count then Exit;
FErrorList.Add('Loading failed!!!');
end;
procedure TMMPlayer.LoadFromStream(Stream:TStream);
var
Tmp:Integer;
begin
FFileName:='*** Stream ***';
FFile.LoadFromStream(Stream);
FErrorList.Add('Loading form the stream...');
Tmp:=FErrorList.Count;
ReLoad;
if Tmp=FErrorList.Count then Exit;
FErrorList.Add('Loading failed!!!');
end;
procedure TMMPlayer.ReLoad;
var
D:DWord;
begin
Close;
FFile.Position:=0;
if ReadString(4,FFile)<>'RIFF' then
begin
FErrorList.Add('Not a RIFF file...');
Exit;
end;
FFile.Read(D,4);
if FFile.Size-8<>D then
begin
FErrorList.Add('Irregular file size of file size info.');
Exit;
end;
if ReadString(4,FFile)<>'WAVE' then
begin
FErrorList.Add('Not a WAVE file...');
Exit;
end;
LookForChunk('fmt ',FFile,FmtChunk);
LookForChunk('data',FFile,DataChunk);
CheckAndPack(FmtChunk);
end;
procedure TMMPlayer.CheckAndPack(FormatChunk:Int64);
var
D:DWord;
begin
FFile.Position:=FormatChunk+4;
FFile.Read(D,4);
if D<>16 then
begin
FErrorList.Add('Unsupported format chunk: compressed or unknown sound format...');
Exit;
end;
FFile.Read(WaveFmt.wFormatTag,2);
FFile.Read(WaveFmt.nChannels,2);
FFile.Read(WaveFmt.nSamplesPerSec,4);
FFile.Read(WaveFmt.nAvgBytesPerSec,4);
FFile.Read(WaveFmt.nBlockAlign,2);
FFile.Read(WaveFmt.wBitsPerSample,2);
WaveFmt.cbSize:=SizeOf(TWAVEFORMATEX);
if WaveFmt.wFormatTag<>1 then
begin
FErrorList.Add('Unsupported chunk size: compressed or extended format...');
Exit;
end;
if WaveFmt.nAvgBytesPerSec<>WaveFmt.nSamplesPerSec*WaveFmt.nBlockAlign then
begin FErrorList.Add('Bad format info...'); Exit; end;
if WaveFmt.nBlockAlign<>WaveFmt.nChannels*(WaveFmt.wBitsPerSample/8) then
begin FErrorList.Add('Bad format info...'); Exit; end;
end;
function TMMPlayer.ReadString(Count:Integer; Stream:TStream):ANSIString;
var
i:Integer;
b:Byte;
begin
Result:='';
for i:=1 to Count do
begin
FFile.Read(b,1);
Result:=Result+Chr(b);
end;
end;
procedure TMMPlayer.LookForChunk(ChunkID:ANSIString; Stream:TStream; var Position:Int64);
var
D:DWord;
CurrChunk:ANSIString;
begin
Position:=Stream.Position;
CurrChunk:='';
while (CurrChunk<>ChunkID) and (Stream.Position<Stream.Size) do
begin
CurrChunk:=ReadString(4,Stream);
if CurrChunk=ChunkID then
begin
Stream.Read(D,4);
Stream.Position:=Stream.Position-8;
Position:=Stream.Position;
Exit;
end;
Stream.Read(D,4);
Stream.Position:=Stream.Position+D;
end;
end;
procedure TMMPlayer.Close;
var
b:Boolean;
begin
if not(WOState) then Exit;
for b:=False to True do
begin
waveOutUnprepareHeader(WO,@sndHdr[b],SizeOf(sndHdr[b]));
FreeMem(sndData[b],WaveFmt.nAvgBytesPerSec);
end;
waveOutClose(WO);
end;
procedure TMMPlayer.Open;
var
b:Boolean;
begin
if WOState then Exit;
if waveOutOpen(@WO,WAVE_MAPPER,@WaveFmt,DWORD(@Ready),0,CALLBACK_FUNCTION)<>MMSYSER R_NOERROR then
begin
FErrorList.Add('Unable to open HWAVEOUT device!!!');
Exit;
end;
for b:=False to True do
begin
GetMem(sndData[b],WaveFmt.nAvgBytesPerSec);
sndHdr[b].lpData:=@sndData[b][0];
sndHdr[b].dwBufferLength:=WaveFmt.nAvgBytesPerSec;
waveOutPrepareHeader(WO,@sndHdr[b],SizeOf(sndHdr[b]));
end;
sndPlay:=False;
WOState:=True;
end;
procedure Ready(hW:HWAVEOUT; uMsg,dwInstance,dwParam1,dwParam2:DWord); stdcall;
begin
if uMsg=WOM_DONE then
begin
PlayNext;
end;
end;
procedure PlayNext;
begin
end;
end.
Просто хочется самому всей этой фигнёй пострадать, а waveOutOpen для callback'а метод класса не берёт: ему обычную процедуру подавай!
Loginov Dmitry (2006-09-30 23:17:00) [6]Без телепатии не обойтись...
ProgRAMmer Dimonych (2006-09-30 23:15:00) [7]Только, кажись, private'ом дело не ограничивается: в public'е тоже не находит. Можно с этим как-то бороться?
Джо (2006-09-30 23:09:00) [8]Тьфу, не "компонента" конечно же, а вообще "класс".
Джо (2006-09-30 23:08:00) [9]> [3] ProgRAMmer Dimonych (30.09.06 23:05)
> А к MemoryStream'у как-нибудь можно добраться? (См. [1])
Что значит "добраться"? Повторю, более расширено: "Private membersвидны только в том же юните, где объявлен класс компонента".
ProgRAMmer Dimonych (2006-09-30 23:05:00) [10]А к MemoryStream'у как-нибудь можно добраться? (См. [1])
Джо (2006-09-30 23:03:00) [11]Private methods никак не вызвать. Они видны только в том же юните, где объявлен класс компонента.
ProgRAMmer Dimonych (2006-09-30 23:01:00) [12]Или хотя бы к его полю FFile:TMemoryStream. Или придётся этот Stream убрать из компонента (или перенести из private в public)?