Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 25.11.2012, 01:01
Dmitry_DM Dmitry_DM вне форума
Активный
 
Регистрация: 07.08.2012
Сообщения: 258
Версия Delphi: Delphi 7
Репутация: 11
По умолчанию Объеденение программ

Здравствуйте! Недавно возник вопрос, поэтому прошу вашей помощи. Есть у меня моя программа для обработки звука и недавно я откопал у себя еще одну небольшую программу: Music Spectrum Analyser. Она в формате dpr вся, без формы, но скомпилированный exe имеет нормальную красивую форму. Я бы хотел интегрировать ее в мою программу, основанную на формах и т.д. Но не знаю как. Единое, что я смог сделать - это запускать ее кнопкой вот так:
Код:
procedure TForm1.sButton1Click(Sender: TObject);
begin
windows.WinExec('histogram.exe',windows.SW_NORMAL);
end;

А хотелось бы, чтобы она была в форме. Есть ли такая возможность и как это осуществить?
Ответить с цитированием
  #2  
Старый 25.11.2012, 01:15
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Решение "в лоб" - вручную поменять стиль окна этой проги на "окно без границ", поставить парентом своё и растянуть на все свое окно. Как - см. WinAPI, SetWindowLong, ...
Решение не в лоб - разобраться в коде этой проги и внедрить в свой код.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием
Этот пользователь сказал Спасибо Bargest за это полезное сообщение:
Dmitry_DM (25.11.2012)
  #3  
Старый 25.11.2012, 01:16
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Цитата:
Сообщение от Dmitry_DM
... Она в формате dpr вся, без формы...
А хотелось бы, чтобы она была в форме. Есть ли такая возможность и как это осуществить?
Есть, прога написана без использования VCL, на "чистом" API, путей здесь пара: или сначало "по одному" компоненту (включая и главную форму) перевести их из рантайма в "нормальный" вид - смотреть в коде где и что появляется и заменять их видимыми компонентами;, либо найти в коде только нужное действие (извнт, не знаю что она "хистограмирует") и использовать только его.
Ответить с цитированием
  #4  
Старый 25.11.2012, 01:25
Dmitry_DM Dmitry_DM вне форума
Активный
 
Регистрация: 07.08.2012
Сообщения: 258
Версия Delphi: Delphi 7
Репутация: 11
По умолчанию

Цитата:
Сообщение от Bargest
Решение "в лоб" - вручную поменять стиль окна этой проги на "окно без границ", поставить парентом своё и растянуть на все свое окно. Как - см. WinAPI, SetWindowLong, ...
Решение не в лоб - разобраться в коде этой проги и внедрить в свой код.
Наверное, легче будет использовать "решение не в лоб". Можно попробовать вытащить нужную часть, главное не нарушить функционал. Но самое интересное, что я не знаю на чем произвести рисование. В самом Music Spectrum Analyser оно так хитро рисуется, что я даже не понял как. Вот выложу ее, может кто посмотрит и даст рекомендации по переводу кода на компонент..
Вложения
Тип файла: rar histogram.rar (138.4 Кбайт, 18 просмотров)
Ответить с цитированием
  #5  
Старый 25.11.2012, 01:29
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Код:
procedure UpdateSpectrum(uTimerID, uMsg, dwUser, dw1, dw2 : Integer); stdcall;
begin
  if isPlayed then
  begin
    OnDrawData;
    OnDrawBar;
    OnDrawWave;
  end;
end;
Вся отрисовка внутри этих функций видимо.
UPD:
Код:
MoveToEx(BarBitmap.DC, I * (ColWidth + 2) + Offset, BarBitmap.aHeight - fftPeaks[i], NIL);
      LineTo(BarBitmap.DC, I * (ColWidth + 2) + ColWidth + Offset, BarBitmap.aHeight - fftPeaks[i]);

      SetRect(aRect, I * (ColWidth + 2) + Offset, BarBitmap.aHeight - FFTFallOff[i], I * (ColWidth + 2) + ColWidth + Offset, BarBitmap.aHeight);
      SetRect(bRect, aRect.Left, BarBitmap.aHeight, aRect.Right, BarBitmap.aHeight - 1);

      J := aRect.Bottom - aRect.Top;
      repeat
        B := 0;
        R := 255 div BarBitmap.aHeight * (aRect.Bottom - aRect.Top - J);
        G := 256 - R;
	FillRect(BarBitmap.DC, bRect, RGB(R, G, B));
	OffsetRect(bRect, 0, -1);
        dec(J);
      until J < 0;
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием
  #6  
Старый 25.11.2012, 01:34
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Ничего у меня там сложного нет. Рисуется на трёх битмапах, затем они копируются на канвас окна.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
Этот пользователь сказал Спасибо angvelem за это полезное сообщение:
Dmitry_DM (25.11.2012)
  #7  
Старый 25.11.2012, 01:39
Dmitry_DM Dmitry_DM вне форума
Активный
 
Регистрация: 07.08.2012
Сообщения: 258
Версия Delphi: Delphi 7
Репутация: 11
По умолчанию

Цитата:
Сообщение от angvelem
Ничего у меня там сложного нет. Рисуется на трёх битмапах, затем они копируются на канвас окна.
Хм.. Все же на Canvas рисование выполняется? Ок, эта ваша программа, я вспомнил. Может вы подскажете где и в каких местах нужно немного по колдовать, что бы перевести эту программу на форму? P.S Программа превосходна!
Ответить с цитированием
  #8  
Старый 25.11.2012, 01:46
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

OnDrawBar - рисует "столбики", OnDrawWave - "волну". Создать битмапы в которые будет происходить отрисовка. Последние строки
Код:
  // update the display
  BitBlt(MainDC, 3, 132, BarBitmap.aWidth, BarBitmap.aHeight, BarBitmap.DC, 0, 0, SRCCOPY);
...
  // update the display
  BitBlt(MainDC, 379, 132, WaveBitmap.aWidth, WaveBitmap.aHeight, WaveBitmap.DC, 0, 0, SRCCOPY);
выводят в нужное место. Если вместо MainDC написать PaintBox1.Canvas.Hadle, то больше никаких изменений не потребуется, кроме координат выода.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
Этот пользователь сказал Спасибо angvelem за это полезное сообщение:
Dmitry_DM (25.11.2012)
  #9  
Старый 25.11.2012, 02:16
Dmitry_DM Dmitry_DM вне форума
Активный
 
Регистрация: 07.08.2012
Сообщения: 258
Версия Delphi: Delphi 7
Репутация: 11
По умолчанию

Цитата:
Сообщение от angvelem
OnDrawBar - рисует "столбики", OnDrawWave - "волну". Создать битмапы в которые будет происходить отрисовка. Последние строки
Код:
  // update the display
  BitBlt(MainDC, 3, 132, BarBitmap.aWidth, BarBitmap.aHeight, BarBitmap.DC, 0, 0, SRCCOPY);
...
  // update the display
  BitBlt(MainDC, 379, 132, WaveBitmap.aWidth, WaveBitmap.aHeight, WaveBitmap.DC, 0, 0, SRCCOPY);
выводят в нужное место. Если вместо MainDC написать PaintBox1.Canvas.Hadle, то больше никаких изменений не потребуется, кроме координат выода.
А как быть с основным окном? Оно же тоже рисуется не на форме. И можно пояснить про координаты вывода? Как их указывать?
Ответить с цитированием
  #10  
Старый 25.11.2012, 02:25
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Эти процедуры рисуют на битмапах, а их потом можешь использвать как угодно и основное окно тебе не требуется. Как я понял ты делаешь не на API, на VCL. Координаты, это первые 2 числа после MainDC.
Предположим вывод на TPainBox:
Код:
  BitBlt(PaintBox1.Canvas.Handle, 0, 0, BarBitmap.aWidth, BarBitmap.aHeight, BarBitmap.Canvas.Handle, 0, 0, SRCCOPY); 
  PaintBox1.Refresh;
на TImage:
Код:
  Image1.Assign(BarBitmap);
Для второго битмапа в том же духе.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
Этот пользователь сказал Спасибо angvelem за это полезное сообщение:
Dmitry_DM (25.11.2012)
  #11  
Старый 25.11.2012, 02:37
Dmitry_DM Dmitry_DM вне форума
Активный
 
Регистрация: 07.08.2012
Сообщения: 258
Версия Delphi: Delphi 7
Репутация: 11
По умолчанию

Цитата:
Сообщение от angvelem
Эти процедуры рисуют на битмапах, а их потом можешь использвать как угодно и основное окно тебе не требуется. Как я понял ты делаешь не на API, на VCL. Координаты, это первые 2 числа после MainDC.
Предположим вывод на TPainBox:
Код:
  BitBlt(PaintBox1.Canvas.Handle, 0, 0, BarBitmap.aWidth, BarBitmap.aHeight, BarBitmap.Canvas.Handle, 0, 0, SRCCOPY); 
  PaintBox1.Refresh;
на TImage:
Код:
  Image1.Assign(BarBitmap);
Для второго битмапа в том же духе.
Ага, с этим понятно. Теперь об открытии файла. Где оно здесь происходит? На что его правильнее всего будет заменить? Я хочу, что бы диалог открытия появлялся при нажатии на кнопку.
Ответить с цитированием
  #12  
Старый 25.11.2012, 02:43
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

При выполнении OpenDialog1.Execute следует код
Код:
function OpenFileName : Boolean;
begin
  Result := False;

  // create a stream from the file
  isMod := mdBassStream;
  ChanDecoder := BASS_StreamCreateFile(False, PAnsiChar(szFileName), 0, 0, BASS_SAMPLE_FLOAT or BASS_STREAM_DECODE or BASS_STREAM_PRESCAN);
  if ChanDecoder = 0 then
  begin
    isMod := mdBassMusic;
    ChanDecoder := BASS_MusicLoad(False, PAnsiChar(szFileName), 0, 0, BASS_SAMPLE_FLOAT or BASS_MUSIC_DECODE or BASS_MUSIC_PRESCAN, 0);
    if ChanDecoder = 0 then
    begin
      // Can't load the file
      isMod := mdBassEmpty;
      MessageBox(0, PAnsiChar(Format('%s "%s"', [szNotOpenFile, szFileName])), 'Error', MB_OK or MB_ICONERROR);
      Exit;
    end;
  end;

  case isMod of
    mdBassStream : ChanPlay := BASS_StreamCreateFile(False, PAnsiChar(szFileName), 0, 0, BASS_SAMPLE_FLOAT);
    mdBassMusic  : ChanPlay := BASS_MusicLoad(False, PAnsiChar(szFileName), 0, 0, BASS_SAMPLE_FLOAT, 0);
  end;
  
  // get byte length
  ChanLen := BASS_ChannelGetLength(ChanDecoder, BASS_POS_BYTE);
  // allocate a buffer for the Channel data
  SetLength(ChanData, ChanLen);
  // decode the stream into the buffer
  ChanLen := BASS_ChannelGetData(ChanDecoder, ChanData, ChanLen);
  
  if ChanPlay <> 0 then
    BASS_ChannelPlay(ChanPlay, False);

  Result := True;
end;

на кнопку будет так
Код:
      if OpenDialog1.Execute then
      begin
        isPlayed := False;
        BASS_ChannelStop(ChanPlay);
        FreeBuffer;
        OpenFileName;
        AllocateWaveData;
        isPlayed := True;
      end;
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #13  
Старый 25.11.2012, 02:47
Dmitry_DM Dmitry_DM вне форума
Активный
 
Регистрация: 07.08.2012
Сообщения: 258
Версия Delphi: Delphi 7
Репутация: 11
По умолчанию

Цитата:
Сообщение от angvelem
При выполнении OpenDialog1.Execute следует код
на кнопку будет так
Код:
      if OpenDialog1.Execute then
      begin
        isPlayed := False;
        BASS_ChannelStop(ChanPlay);
        FreeBuffer;
        OpenFileName;
        AllocateWaveData;
        isPlayed := True;
      end;
И тот большой код не требуется? Все заменяется эти маленьким компактным кодом?
Ответить с цитированием
  #14  
Старый 25.11.2012, 02:56
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Этот при клике на кнопку. Далее вызываются последовательно: FreeBuffer, OpenFileName, AllocateWaveData.

Может сделать проще. Накидай проект, как ты его представляешь и скажи, что и куда прикрутить.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.

Последний раз редактировалось angvelem, 25.11.2012 в 03:06.
Ответить с цитированием
  #15  
Старый 25.11.2012, 15:02
Dmitry_DM Dmitry_DM вне форума
Активный
 
Регистрация: 07.08.2012
Сообщения: 258
Версия Delphi: Delphi 7
Репутация: 11
По умолчанию

Цитата:
Сообщение от angvelem
Этот при клике на кнопку. Далее вызываются последовательно: FreeBuffer, OpenFileName, AllocateWaveData.

Может сделать проще. Накидай проект, как ты его представляешь и скажи, что и куда прикрутить.
Сделаем проще: вот, что я хочу - я вынес в отдельный проект только муз плеер, что бы не запутаться в 1600 строк моей программы. В муз плеере есть свои недочеты. Первое - это неверное удаление строк из play листа. Кнопка del удаляет именно первую строку listbox, а не ту, что выделена. Второе - это эквалайзер. Если стоит обычный, то все норм, а если другой, то при несколько разовом нажатии "пауза\воспр - пауза\воспр" - звук искажается по неизвестной причине.. А теперь о Music Spectrum Analyser. Я хочу, что бы выбор файла производился еще в моей программе. А второе - это чтобы переключателем combobox переключалась моя визуализация и ваша, но по умолчанию стояла ваша. И размер рисованного окна должен быть 704*177 (это важно). P/S: это конечно не обязательно, но если нетрудно можно ли заделать выбор канала в правом нижнем окне визуализации и поставить radiogroup с выбором рисовать левый, правый или оба канала? Заранее благодарен за помощь!!!
Вложения
Тип файла: rar Новый проэкт.rar (458.2 Кбайт, 6 просмотров)

Последний раз редактировалось Dmitry_DM, 25.11.2012 в 15:13.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 17:42.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter