Здравствуйте! У меня проблема с сабжем (скорее всего). Вызываю GetOpenFileName, и программа вылетает. Структуру заполнял так: Код (Text): mov ofn.lStructSize,SIZEOF OPENFILENAME push hWin pop ofn.hwndOwner push hInstance pop ofn.hInstance mov ofn.lpstrFilter,offset aFilter push aFilterIndex pop ofn.nFilterIndex mov ofn.lpstrFile,offset aFileName push lFileName pop ofn.nMaxFile mov ofn.lpstrTitle,offset aCaption mov ofn.lpstrFileTitle,NULL mov ofn.lpstrCustomFilter,NULL mov ofn.Flags,OFN_EXPLORER or OFN_FILEMUSTEXIST mov ofn.lCustData,NULL mov ofn.lpTemplateName,NULL aFilter db 'Звук (*.wav)','*.wav',0,0 aFilterIndex dd 1 aCaption db 'Открыть файл',0 aFileName db 0 lFileName dd 256 помогите пожалуйста!
1. Фильтр должен выглядеть так: aFilter db 'Звук (*.wav)',0,'*.wav',0,0 2. aFileName - это буфер, в который будет записано имя выбранного файла. А у тебя что? 3. ofn.lpstrFileTitle тоже должен указывать на буфер (imho)
SteelRat написал. правильно? invoke RtlZeroMemory,addr ofn,SIZEOF OPENFILENAME rmn 1. исправил. 2. это так что ли: aFileName db 256 dup (0) ? 3. в справке написано, что "This member can be NULL". P.S. всё равно не работает.
Структура вот: Код (Text): struct OPENFILENAME DWORD lStructSize; HWND hwndOwner; HINSTANCE hInstance; LPCTSTR lpstrFilter; LPTSTR lpstrCustomFilter; DWORD nMaxCustFilter; DWORD nFilterIndex; LPTSTR lpstrFile; DWORD nMaxFile; LPTSTR lpstrFileTitle; DWORD nMaxFileTitle; LPCTSTR lpstrInitialDir; LPCTSTR lpstrTitle; DWORD Flags; WORD nFileOffset; WORD nFileExtension; LPCTSTR lpstrDefExt; DWORD lCustData; LPOFNHOOKPROC lpfnHook; LPCTSTR lpTemplateName; ends Переменные типа nMax должны содержать размеры соответствующих буферов. Переменные типа LPSTR должны содержать адреса соответствующих буферов. Ошибка в твоём коде: .... mov ofn.lpstrFile,offset aFileName push lFileName pop ofn.nMaxFile .... Под lFileName не зарезервирован буфер. ofn.nMaxFile должен содержать размер буфера lpstrFile. ofn.lpstrFile - Указатель на этот буфер. Вот карявый, работающий пример (FASM): ............ lpfilter db 'Звук - *.WAV',0,'*.wav',0,0 lpfile rb 128 sfile = $-lpfile lpfiletitle rb 128 sfiletitle = $-lpfiletitle ofnstr OPENFILENAME osize,0,0,lpfilter,0,0,0,lpfile,sfile,lpfiletitle,sfiletitle,0,0,0,0,0 ,0,0,0,0 osize=$-ofnstr ............ ............ mov EAX,[wc.hInstance] mov dword [ofnstr.hInstance],EAX invoke GetOpenFileName,ofnstr .............
я сделал вместо заполнения структуры OPENFILENAME использование макроса OpenFileDlg из состава макросов Masm32. Очень удобно, но есть одно но. Как мне получить строку из памяти? Можно использовать lodsb, но тогда как мне узнать длину строки - ведь это же путь, а путь - переменная величина.
DPX Если не улавливаешь разницу то тебе еще рано программировать. Ты заполнил структуру определенными значениями, после обнулил ее, т.е., уточняю, затер все эти значения нулями и вызвал функцию. Что ты хочешь в таком случае от GetOpenFileName, если ты передал ей структуру с нулевыми параметрами?
да нет, я не это имел в виду. я, наверно, упустил то, что сначала поставил RtlZeroMemory, а потом вызов функции. но сейчас у меня уже другое исполнение этого самого Open Dialog, так что структура уже не требуется, меня больше волнует, как получить строку из памяти...
Длина строки равна разности двух адресов - начала и конца строки. Начало - адрес буфера, в котором строка. А что является признаком окончания строки?
DPX Что? т.е. тебе уже все-равно где в твоем исходнике была ошибка? Вот кусок кода, тут и проверка на то что вернула GetOpenFileName и использование строки: Код (Text): case WM_COMMAND: switch(LOWORD(wParam)) { case IDC_OPEN: RtlZeroMemory(&ofn, sizeof(ofn)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hDlg; ofn.lpstrFilter = "Executable Files (*.exe)\0*.exe\0"; ofn.lpstrFile = ExeName; ofn.nMaxFile = sizeof(ExeName); ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_EXPLORER | OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_NONETWORKBUTTON; if(GetOpenFileName(&ofn)) SetDlgItemText(hDlg, IDC_EDIT, ExeName); else { SetDlgItemText(hDlg, IDC_EDIT, NULL); ExeName[0] = '\0'; } break;
всем спасибо, я уже нашёл такой алгоритм: Код (Text): mov lpFileName,OpenFileDlg(hWin,hInstance,offset aCaption,offset aFilter) .if BYTE PTR [eax]==0 jmp ex .endif invoke szLen,lpFileName add eax,1 mov ecx,eax mov esi,[lpFileName] lea edi,CurrFileName rep movsb ex: lpFileName LPSTR ? CurrFileName db ? для того чтобы это работало, надо включить comdlg32 и masm32 .inc и .lib файлы