Для примера: допустим, вы хотите ввести в ваше приложение возможность воспроизведения звуковых файлов при их выделении в окне диалога (как, например, сделано в программе FruityLoops при выборе сэмпла). Для этого необходимо создать процедуру, в которую будут поступать уведомительные сообщения от окна диалога. При поступлении определённого сообщения мы получим имя файла и попытаемся его воспроизвести.
Единственный параметр вышеупомянутых функций - указатель на структуру OPENFILENAME. Чтобы установить ловушку, необходимо:
Демонстрационный код:
#include <mmsystem.hpp> // для sndPlaySound и waveOutGetNumDevs // процедура - ловушка UINT APIENTRY OFNHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam) { if(uiMsg==WM_NOTIFY && ((OFNOTIFY*)lParam)->hdr.code==CDN_SELCHANGE) { char fName[MAX_PATH]; if(CommDlg_OpenSave_GetFilePath(((OFNOTIFY*)lParam)->hdr.hwndFrom,fName,MAX_PATH)>=0) { if(ExtractFileExt(fName).UpperCase()==".WAV" && waveOutGetNumDevs()) sndPlaySound(fName, SND_ASYNC); // асинхронное воспроизведение } } return 0; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { char buff[MAX_PATH] = {'\0'}; OPENFILENAME ofn; ZeroMemory(&ofn, sizeof ofn); ofn.lStructSize = sizeof ofn; ofn.hwndOwner = Handle; ofn.lpstrFilter = "Файлы WAVE (*.wav)\0*.wav\0\0"; ofn.lpstrFile = buff; ofn.nMaxFile = MAX_PATH; ofn.lpstrTitle = "Выбор звукового файла"; ofn.Flags = OFN_HIDEREADONLY | OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_ENABLEHOOK; ofn.lpfnHook = OFNHookProc; GetOpenFileName(&ofn); sndPlaySound(NULL,0); // остановка воспроизведения } |
Итак, при нажатии на кнопку мы создаём и инициализируем структуру OPENFILENAME. Поле lpfnHook мы инициализировали адресом процедуры OFNHookProc. Далее мы вызываем саму функцию, и механизм запускается.
Теперь рассмотрим саму процедуру ловушки - OFNHookProc. Обратите внимание, что её прототип идентичен прототипу обычной оконной процедуры.
Мы обрабатываем сообщение WM_NOTIFY. В данном случае, lParam сообщения является указателем на структуру OFNOTIFY.
Мы проверяем равенство параметра code вложенной структуры NMHDR значению CDN_SELCHANGE.
Если условие равно true, это означает, что в диалоге изменился выбранный элемент.
Далее мы получаем имя выбранного файла с помощью макроса CommDlg_OpenSave_GetFilePath,
что эквивалентно отправке диалогу сообщения CDM_GETFILEPATH. После этого проверяем расширение файла
и количество звуковых устройств, установленных в системе (waveOutGetNumDevs()). Если всё нормально, воспроизводим файл.
Недостаток этого примера: