Вожусь с плеером.Ктонибудь не подскажет одну вещь: допустим я использую свой плеер по умолчанию (
if not ('' = System.ParamStr(1)) then) Так вот когда я не закрывая первого экземпляра плеера открываю другой муз. файл, то открывается второй экземпляр плеера и там играет вторая мелодия. А я хочу чтобы 2-я мелодия играла в первом экземпляре.
with MediaPlayer1 do
begin
try
Filename := System.ParamStr(1);
{Ну и так далее...}
Алгоритм такой:
1) Проверяешь при старте программы (onCreateForm) не запущен ли еще один экземпляр твоего плеера. Как сделать смотри http://forum.pascal.net.ru/index.php?showtopic=11847&hl=%F1%EF%E8%F1%EE%EA+%E7%E0%E4%E0%F7
2) Если экземпляр есть, то шли сообщение ему (PostMessage), в котором указано имя нового файла для воспроизведения и завершай работу программы (только не первого экземпляра ;) ).
3) Организуй обработку своего события (т.н. сообщения - например const WM_ADD_IN_PLAYLIST = WM_USER + 1010; ) как это сделать - пример из стандартного хелпа:
//The following code handles a custom message that the application sends to itself when a file is ready for reading.
const
WM_FILEREADY = WM_USER + 2000;
procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnMessage := AppMessage;
end;
procedure TForm1.AppMessage(var Msg: TMsg; var Handled: Boolean);
begin
if Msg.message = WM_FILEREADY then
begin
Memo1.Lines.LoadFromFile(StrPas(PChar(Msg.lParam)));
Handled := True;
end;
{ for all other messages, Handled remains False }
{ so that other message handlers can respond }
end;
Примерно что-то вроде этого думал, но не знал как сделать. Спасибо.
PostMessage(hWnd, WM_FILEREADY, 0, MusicFileName);где hWnd - хендлер уже запущенного твоего плеера (как его найти я давал ссылку вверху).
Close;
Как я понимаю на этапе использования PostMessage, ты уже уверен что твое приложение запущенно. А значит можешь идентифицировать его, например, по названию оконного заголовка или класса окна. Для этого в WinApi есть функция http://msdn2.microsoft.com/en-us/library/ms633499.aspx. Первый параметр - название класса окна, второй - название заголовка окна. Есть возможность искать только по одному из параметров (в случае когда второй неизвестен), подставляя под значение другого nil, но гарантия нахождения именно твоего окна увеличивается при задании сразу двух параметров. Результат этой функции, в случае успешного выполнения, вернет handle твоего окна (того, что стартовало первым). Именно за этим мы использовали FindWindow, ибо первый аргумент функции http://msdn2.microsoft.com/en-us/library/ms644944.aspx и есть handle окна, которому ты хочешь отправить сообщение. В качестве Msg можешь указать WM_ADD_IN_PLAYLIST (из поста hiv'a), а полезную нагрузку будут выполнять два оставшихся параметра. Вернее в нашем случае понадобиться только один. Тип каждого из них это DWord, который занимает 4 байта. Как раз как и pointer или pChar... Т.е. ты просто приводишь свою строку к DWord и передаешь получившиеся как аргумент в функцию.
dword(PChar). Хотя правильнее будет WPARAM(PChar) или LPARAM (PChar), в соответствии с типом аргумента в котором ты захочешь передавать данные.
Пасибо ребят! (если будут вопросы - отпишусь ) а пока - +1 Bokul и +1 hiv! Вы реально помогли!
Ага, сейчас прямо... Все дела забросим и будем файлы плодить
mailslots никто не отменял: http://www.delphikingdom.ru/asp/viewitem.asp?catalogid=904
Блин, при компиляции программы FindWindow сразу находит первый экземпляр..Что не так?
procedure TForm1.FormCreate(Sender: TObject);
var
d: PChar;
h: hwnd;
begin
Application.OnMessage := AppMessage;
d := PChar(System.ParamStr(1));
h := FindWindow(nil,'MP3 1.8.0.7');
if h<>0 then begin
PostMessage(h,WM_ADD_TO_PLAYLIST,0,lparam(d));
Application.Terminate;
end;
end;
Ну, во-первых, ты где прописал Caption формы? В Object Inspector-е? Надо бы здесь:
begin
Application.OnMessage := AppMessage;
d := PChar(System.ParamStr(1));
h := FindWindow(nil,'MP3 1.8.0.7'); // <--- Здесь ищешь именно первое приложение
if h<>0 then begin
PostMessage(h,WM_ADD_TO_PLAYLIST,0,lparam(d));
Application.Terminate;
end;
// Вот тут, уже после FindWindow, можно менять Caption формы...
Form1.Caption := 'MP3 1.8.0.7';
...
Ага,я понял.Спасибо за помощь!
Это опять я.
Сообщение от второго экзэмпляра первому передается,только первое нифига нормально обработать не может:
procedure TForm1.FormCreate(Sender: TObject);
var
d: PChar;
h: hwnd;
begin
Application.OnMessage := AppMessage;
d := PChar(System.ParamStr(1));
h := FindWindow(nil,'MP3 1.8.0.7');
if (h<>0) then begin
PostMessage(h,WM_ADD_TO_PLAYLIST,0,lparam(d));
Application.Terminate;
end;
end;
procedure TForm1.AppMessage(var Msg: TMsg; var Handled: Boolean);
begin
if Msg.message = WM_ADD_TO_PLAYLIST then
begin
MediaPlayer1.FileName := StrPas(PChar(Msg.lParam)); {<-------- Вот тут произходит ошибка!!!!!}
MediaPlayer1.Open;
procedure TForm1.AppMessage(var Msg: TMsg; var Handled: Boolean);
var s: string;
begin
if Msg.message = WM_ADD_TO_PLAYLIST then
begin
s := StrPas(PChar(Msg.lParam));
MediaPlayer1.FileName := s; // Вот так ошибка не произойдет, если передано правильное имя файла
MediaPlayer1.Open;
...
Теперь ошибка происходит в этой строке:
s := StrPas(PChar(Msg.lParam));
У меня не происходит... Покажи, как ты передаешь имя файла, может там проблема...
Добавлено через 4 мин.
А, у тебя берется параметр командной строки... Я сделал вот так:
- все отработало...
var
d: PChar; // Глобально !!!
procedure TForm1.FormCreate(Sender: TObject);
var h: hwnd;
begin
Application.OnMessage := AppMessage;
d := PChar(ExtractFilePath(ParamStr(0)) + 'sound.wav');
h := FindWindow(nil,'MP3 1.8.0.7');
if h<>0 then begin
PostMessage(h,WM_ADD_TO_PLAYLIST,0,lparam(d));
Application.Terminate;
end;
Form1.Caption := 'MP3 1.8.0.7';
...
end;
const
WM_ADD_TO_PLAYLIST = WM_USER + 1010;
procedure TForm1.AppMessage(var Msg: TMsg; var Handled: Boolean);
var s: string;
begin
if Msg.message = WM_ADD_TO_PLAYLIST then
begin
s := StrPas(PChar(Msg.lParam));
MediaPlayer1.FileName := S;
MediaPlayer1.Open;
Handled := True;
end;
end;
В смысле как передаю? System.ParamStr(1)?
Добавлено через 8 мин.
Все равно пишет ошибку! (сволочь (извините))
Правильнее будет - так:
var
d: PChar;
procedure TForm1.FormCreate(Sender: TObject);
var
h: hwnd;
begin
Application.OnMessage := AppMessage;
d := StrNew(PChar(System.ParamStr(1))); // Выделяем память под строку !!!
h := FindWindow(nil,'MP3 1.8.0.7');
if (h<>0) then begin
PostMessage(h,WM_ADD_TO_PLAYLIST,0,lparam(d));
Application.Terminate;
end;
end;
procedure TForm1.AppMessage(var Msg: TMsg; var Handled: Boolean);
var s: string;
begin
if Msg.message = WM_ADD_TO_PLAYLIST then
begin
s := StrPas(PChar(Msg.lParam));
MediaPlayer1.FileName := s;
MediaPlayer1.Open;
...
Кажется я понял проблему...
Смотри,так работает:
d := StrNew(PChar('D:\1.mp3'));
d := StrNew(PChar(System.ParamStr(1)));
Хм.... Может глупость...
А что если открыть сокет на 127.0.0.1 (т.е. локально) и слушать его на поступление имен файлов, которые нужно проиграть.
Нет,нужно именно через Post или SendMessage
Ну а привести тогда код любого из этих путей можешь?..я с этим не работал.
Добавлено через 3 мин.
Вообще,я понял что ParamStr с PostMessage не катит,да?
const
WM_ADD_TO_PLAYLIST = WM_USER + 1010;
procedure TForm1.AppMessage(var Msg: TMsg; var Handled: Boolean);
var
s: string;
begin
if Msg.message = WM_ADD_TO_PLAYLIST then
begin
SetLength(S, MSG.lParam + 1);
GlobalGetAtomName(MSG.wParam, PChar(S), MSG.LParam + 1);
MediaPlayer1.FileName := S;
MediaPlayer1.Open;
Handled := True;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
h: hwnd;
s: string;
myAtom: TAtom;
begin
Application.OnMessage := AppMessage;
s := ParamStr(1);
h := FindWindow(nil,'MP3 1.8.0.7');
if h <> 0 then begin
myAtom := GlobalAddAtom(PChar(s));
PostMessage(H, WM_ADD_TO_PLAYLIST, myAtom, Length(s));
GlobalDeleteAtom(myAtom);
Application.Terminate;
end;
Form1.Caption := 'MP3 1.8.0.7';
2volvo
Ты крууут!