Хостинг портала RFpro.ru: Московский хостер Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64 РАССЫЛКИ ПОРТАЛА RFPRO.RU Лучшие эксперты по данной тематике | Номер выпуска: | 1486 | | Дата выхода: | 05.11.2011, 06:30 | | Администратор рассылки: | Лысков Игорь Витальевич (Старший модератор) | | Подписчиков / экспертов: | 192 / 60 | | Вопросов / ответов: | 1 / 1 | Консультация # 184349: Уважаемые эксперты! Пожалуйста, ответьте на вопрос: Разработать программу (MASM 32), на форму поставить кнопки, по нажатию одной на экран выведется новое окно с заданной в файле текстовой информацией, по нажатию второй ─ выведется окно с графической информацией. Новое окно ─ не типа MessageBox, а стандартная форма. При этом файл... Консультация # 184349: Уважаемые эксперты! Пожалуйста, ответьте на вопрос:
Разработать программу (MASM 32), на форму поставить кнопки, по нажатию одной на экран выведется новое окно с заданной в файле текстовой информацией, по нажатию второй ─ выведется окно с графической информацией. Новое окно ─ не типа MessageBox, а стандартная форма. При этом файлы с исходной информацией получать в результате диалога.
И еще можно комментариев побольше в проге))) Дата отправки: 31.10.2011, 06:15 Вопрос задал: Петров Юрий Иванович (Посетитель) Всего ответов: 1 Страница онлайн-консультации » Консультирует Лысков Игорь Витальевич (Старший модератор): Здравствуйте, Петров Юрий Иванович! Программировать под Windows несколько сложнее, чем под ДОС. Без основательного ознакомления с принципами программирования понять очень сложно. Настоятельно рекомендую это сделать в первую очередь. По программе: Для запроса имени файла использовал стандартный диалог. Реализовал использование диалогов без шаблонов. Имеем немодальные окна, обратите внимание, что очередь сообщений у них одна с основным окном! Можно создавать много окон, ограничений нет Разбирайтесь...
Код : .386 ;32-битный код .model flat, stdcall ;модель памяти и соглашение о вызове параметров option casemap :none ;различаем большие-малые буковки ; include files include \masm32\include\windows.inc include \masm32\include\masm32.inc include \masm32\include\gdi32.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc include \masm32\include\comdlg32.inc include \masm32\macros\macros.asm ; libraries includelib \masm32\lib\masm32.lib includelib \masm32\lib\gdi32.lib includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\comdlg32.lib ; Прототипы функций WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD TopXY PROTO :DWORD,:DWORD RegisterWinClass PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD MsgLoop PROTO :DWORD Main PROTO PushButton PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD CreatePopWindow PROTO: DWORD,:DWORD,:DWORD GetFileName PROTO :DWORD,:DWORD,:DWORD SetText PROTO :DWORD,:DWORD TextWndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD CalcSize PROTO :DWORD,:DWORD,:DWORD,:DWORD BmpWndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD ;коды используемых ресурсов IDI_ICON equ 500 IDC_TEXT equ 201 IDC_BMP equ 301 IDC_EXIT equ 401 IDC_EDIT equ 601 BitMapData struct hBmap dd ? hMhdc dd ? BitMapData ends .data currButton dd IDC_EXIT .data? hInstance dd ? ;описатель экземпляра процесса CommandLine dd ? ;командная строка hIcon dd ? ;описатель пиктограммы hCursor dd ? ;описатель курсора sWid dd ? ;ширина экрана sHgt dd ? ;высота экрана hWnd dd ? ;описатель главного окна приложения rectBMP RECT <> ;координаты для вывода BMP в окне sizeBMP POINT <> ;размер BMP szNameTXT db 256 dup (?) ;для хранения текущего имени txt-файла szNameBMP db 256 dup (?) ;для хранения текущего имени bmp-файла .code ;макро rv запускает указанную функцию и присваивает переменной возвращаемый результат start: mov hInstance, rv(GetModuleHandle, NULL) ;описатель экземпляра процесса mov CommandLine,rv(GetCommandLine) ;командная строка mov hIcon, rv(LoadIcon,hInstance,IDI_ICON) ;пиктограмма mov hCursor, rv(LoadCursor,NULL,IDC_ARROW) ;курсор mov sWid, rv(GetSystemMetrics,SM_CXSCREEN);ширина экрана mov sHgt, rv(GetSystemMetrics,SM_CYSCREEN);высота экрана call Main ;запускаем invoke ExitProcess, eax ;завершаем процесс ; ------------------------------------------------------------------------- ;Макро STRING строит строку в сегменте .data Main proc STRING szClassName,"MainDialog_Class" ;класс основного окна STRING szTextClassName,"TextDialog_Class" ;класс диалога для вывода текста STRING szBmpClassName,"BmpDialog_Class" ;класс диалога для вывода графики STRING szHeader,"Задание" ;заголовок основного окна invoke RegisterWinClass,ADDR WndProc,ADDR szClassName, ;регистрируем класс окна hIcon,hCursor,COLOR_BTNFACE+1 invoke RegisterWinClass,ADDR TextWndProc, ;регистрируем класс окна для вывода текста ADDR szTextClassName,hIcon,hCursor,COLOR_BTNFACE+1 invoke RegisterWinClass,ADDR BmpWndProc, ;регистрируем класс окна для вывода графики ADDR szBmpClassName,hIcon,hCursor,COLOR_BTNFACE+1 ;создаем основное окно invoke CreateWindowEx,WS_EX_LEFT, ADDR szClassName, ADDR szHeader, WS_CAPTION or WS_SYSMENU or WS_MINIMIZEBOX, 0,0,0,0, NULL,NULL, hInstance,NULL mov hWnd,eax ;сохраним описатель окна invoke ShowWindow,hWnd, SW_SHOWNORMAL ;показать invoke UpdateWindow,hWnd ;обновить invoke MsgLoop,hWnd ;цикл обработки сообщений ret Main endp ;макро m2m делает push + pop ;регистрируем класс окна RegisterWinClass proc lpWndProc:DWORD, lpClassName:DWORD, Icon:DWORD, Cursor:DWORD, bColor:DWORD LOCAL wc:WNDCLASSEX mov wc.cbSize, sizeof WNDCLASSEX mov wc.style, 0 m2m wc.lpfnWndProc, lpWndProc mov wc.cbClsExtra, NULL mov wc.cbWndExtra, 4 ;зарезервируем 4 байта для хранения информации m2m wc.hInstance, hInstance m2m wc.hbrBackground, bColor mov wc.lpszMenuName, NULL m2m wc.lpszClassName, lpClassName m2m wc.hIcon, Icon m2m wc.hCursor, Cursor m2m wc.hIconSm, Icon invoke RegisterClassEx, ADDR wc ret RegisterWinClass endp ;цикл обработки сообщений MsgLoop proc uses esi edi, hwnd:DWORD LOCAL msg:MSG xor edi, edi ; clear EDI lea esi, msg ; Structure address in ESI .while TRUE invoke GetMessage, esi, edi, edi, edi .break .if (!eax) ;пропустим сообщения для дочерних окон invoke IsDialogMessage, hwnd, esi .if (!eax) INVOKE TranslateMessage, addr msg INVOKE DispatchMessage, addr msg .endif .endw mov eax, msg.wParam ret MsgLoop endp ;функция основного окна WndProc proc hWin:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD LOCAL Wwd:DWORD, \ ;ширина основного окна Wht:DWORD, \ ;высота основного окна Wtx:DWORD, \ ;X-координата начала окна Wty:DWORD ;Y-координата начала окна if uMsg == WM_CREATE STRING sButtonText,"Текст" STRING sButtonBmp, "Графика" STRING sButtonExit,"Выход" ;создаем три кнопки invoke PushButton,ADDR sButtonText,hWin,WS_TABSTOP,40,20,100,25,IDC_TEXT invoke PushButton,ADDR sButtonBmp,hWin,WS_TABSTOP,40,50,100,25,IDC_BMP invoke PushButton,ADDR sButtonExit,hWin,WS_TABSTOP or BS_DEFPUSHBUTTON,40,80,100,25,IDC_EXIT ;дадим фокус "Выход"-у invoke SetFocus, eax ;посчитаем координаты окна mov Wwd, 180 mov Wht, 160 invoke TopXY,Wwd,sWid mov Wtx, eax invoke TopXY,Wht,sHgt mov Wty, eax ;разместим окно в центре экрана invoke MoveWindow, hWin, Wtx, Wty, Wwd, Wht, 0 elseif uMsg == WM_SETFOCUS ;при получении окном фокуса, дадим фокус последней использованной кнопке invoke GetDlgItem, hWin, currButton invoke SetFocus, eax elseif uMsg == WM_COMMAND STRING szFilterTXT,'Текстовые Файлы (*.txt)',0,'*.txt',0 ;фильтр для выбора текстовых файлов STRING szFilterBMP,'Графические Файлы (*.bmp)',0,'*.bmp',0 ;фильтр для выбора графическых файлов STRING szTitle,'Введите имя открываемого файла' ;заголовок для диалога выбора файлов ;запомним код активной кнопки m2m currButton, wParam ;отрабатываем кнопки .if wParam == IDC_TEXT ;Текст ;запросим имя TXT-файла invoke GetFileName, addr szNameTXT, addr szFilterTXT, addr szTitle ;что-то ввели? .if eax != 0 invoke CreatePopWindow, hWin, addr szNameTXT, addr szTextClassName .endif .elseif wParam == IDC_BMP ;Графика ;запросим имя TXT-файла invoke GetFileName,offset szNameBMP,offset szFilterBMP,offset szTitle ;что-то ввели? .if eax != 0 invoke CreatePopWindow, hWin, addr szNameBMP, addr szBmpClassName .endif .elseif wParam == IDC_EXIT ;Выход ;сымитируем "крестик" сверху или Ctrl-F4 invoke SendMessage, hWin, WM_CLOSE, 0, 0 .endif elseif uMsg == WM_CLOSE ;завершаемся: посылаем в очередь ноль, по которому произойдет выход из отработки invoke PostQuitMessage,NULL else ;все остальное отрабатывается стандартно invoke DefWindowProc,hWin,uMsg,wParam,lParam ret ;возврат из "ненаших" отработок endif return 0 ;возврат из "наших" отработок WndProc endp ;вычисляем координату начала отрезка длины wDim, чтобы он был посередине отрезка длины sDim TopXY proc wDim:DWORD, sDim:DWORD mov eax, sDim sub eax, wDim shr eax, 1 ret TopXY endp ;создание дочернего окна (родитель hParent) класса pClassName ;и с именем файла pfileName для заполнения CreatePopWindow proc hParent:dword, pfileName:dword, pClassName:dword local hWindow:dword ;создаем окно invoke CreateWindowEx,0, pClassName, ;имя класса pfileName, ;имя файла в заголовок WS_CAPTION or WS_SIZEBOX or WS_SYSMENU or \ WS_POPUP or DS_MODALFRAME, 0,0,0,0, hParent,NULL, hInstance,pfileName ;передадим имя файла параметром mov hWindow,eax ;сохраним описатель окна invoke ShowWindow, hWindow, SW_SHOWNORMAL ;показать invoke UpdateWindow, hWindow ;обновить return hWindow ;вернем описатель окна CreatePopWindow endp ;вводим имя файла GetFileName proc uses edi, pFName:dword, \ ;имя текущего файла pFilter:dword,\ ;фильтр pTitle:dword ;заголовок диалога LOCAL ofn:OPENFILENAMEA STRING szCurrPath,"." ;начальный путь - текущая папка lea edi, ofn mov edx, edi mov ecx, (size OPENFILENAMEA) / 4 xor eax, eax rep stosd mov [(OPENFILENAMEA ptr [edx]).lStructSize], size OPENFILENAMEA m2m [(OPENFILENAMEA ptr [edx]).lpstrFile], pFName ;имя текущего файла mov [(OPENFILENAMEA ptr [edx]).nMaxFile], 256 ;его макс длина m2m [(OPENFILENAMEA ptr [edx]).lpstrFilter], pFilter ;фильтр m2m [(OPENFILENAMEA ptr [edx]).lpstrTitle], pTitle ;заголовок диалога mov [(OPENFILENAMEA ptr [edx]).lpstrInitialDir], offset szCurrPath ;текущий путь mov [(OPENFILENAMEA ptr [edx]).Flags], OFN_PATHMUSTEXIST or OFN_FILEMUSTEXIST or OFN_HIDEREADONLY ;параметр - адрес структуры invoke GetOpenFileName, edx ;вызываем ret ;возвращает 1, если файл выбран, или 0, если нет GetFileName endp ;создание кнопки на позиции (a, b), размером (wd, ht), со стилем style и с идентификатором ID PushButton proc lpText:DWORD,hParent:DWORD,style:DWORD, a:DWORD,b:DWORD,wd:DWORD,ht:DWORD,ID:DWORD STRING btnClass,"BUTTON" mov eax, style or eax, WS_CHILD or WS_VISIBLE ;дочернее и видимое даем по-умолчанию invoke CreateWindowEx,0, ADDR btnClass,lpText, eax, a,b,wd,ht,hParent,ID, hInstance,NULL ret ;в AX handle кнопки PushButton endp ;Подпрограммы для окна с текстом --------------------- ;загрузка текста в редактор окна из файла ;hwnd - описатель редактора, куда мы "отдадим" текст ;szName - имя файла SetText proc uses esi edi ebx, hwnd:dword, szName:dword local dwCount:dword, dwHigh:dword ;младшее и старшее двойное слово длины файла ;открываем файл mov ebx, rv(CreateFile, szName,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0) ;узнаем длину файла mov dwCount, rv(GetFileSize, ebx, ADDR dwHigh) ;резервируем память под содержимое файла ;в конце добавим 1 байт для завершающего нуля lea edi, dwCount mov eax, [edi] inc eax ;esi - адрес буфера mov esi, rv(GlobalAlloc, GMEM_FIXED, eax) ;читаем файл ;edi - адрес переменной с длиной ;ebx - описатель файла invoke ReadFile, ebx, esi, [edi], edi, 0 ;закрываем файл invoke CloseHandle, ebx ;читаем реальную длину файла mov eax, [edi] ;завершим нулем mov byte ptr [eax+esi], 0 ;выведем в Edit invoke SetWindowText, hwnd, esi ;освободим память invoke GlobalFree, esi ret SetText endp ;функция окна "Текст" TextWndProc proc hWin:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD LOCAL Wwd:DWORD, \ ;ширина основного окна Wht:DWORD ;высота основного окна if uMsg == WM_CREATE ;создадим дочернее окно-редактор с атрибутами многострочный, readonly, с прокруткой ;размеры и положение зададим позже STRING edtClass, "edit" invoke CreateWindowEx,0, ADDR edtClass,NULL, \ WS_VISIBLE or WS_CHILD or ES_MULTILINE or ES_READONLY or\ ES_AUTOHSCROLL or ES_AUTOVSCROLL or \ WS_HSCROLL or WS_VSCROLL, \ 0,0,0,0,hWin,IDC_EDIT, \ hInstance,NULL .if (eax) mov ecx, lParam ;lParam-адрес структуры, в начале-параметр-адрес имени файла invoke SetText, eax, [ecx] ;заполняем редактор .endif ;посчитаем координаты окна mov eax, sWid sub eax, 300 mov Wwd, eax mov eax, sHgt sub eax, 300 mov Wht, eax ;установим позицию окна "Текст" invoke MoveWindow, hWin, 150, 150, Wwd, Wht, 0 elseif uMsg == WM_SIZE ;установим позицию окна редактора invoke GetDlgItem, hWin, IDC_EDIT ;eax = hEdit mov edx, lParam ;размер клиентской части mov ecx, edx and edx, 0ffffh ;младшее слово - ширина shr ecx, 16 ;старшее - высота invoke MoveWindow, eax, 0, 0, edx, ecx, 0 else ;остальное - по-умолчанию invoke DefWindowProc,hWin,uMsg,wParam,lParam ret endif return 0 ;возврат наших отработок TextWndProc endp ;считаем размеры и координаты изображения ;hBmp - описатель изображения ;hWin - окно, куда будем выводить картинку ;pRectBmp - адрес RECT, куда запишем позицию и размер вывода картинки ;pSizeBMP - ширина и высота картинки CalcSize proc uses edi esi, hBmp:dword, hWin:HWND, pRectBMP:dword, pSizeBMP:dword LOCAL BMap:BITMAP, rc:RECT invoke GetObject, hBmp, size BITMAP, ADDR BMap ;узнаем размер картинки invoke GetClientRect, [hWin], ADDR rc ; и размер окна mov edi, [pRectBMP] ;адрес RECT mov [(RECT ptr [edi]).left], 2 ;начальный X вывода mov [(RECT ptr [edi]).top], 2 ;начальный Y вывода mov eax, [rc.right] sub eax, 4 mov [(RECT ptr [edi]).right], eax ;ширина области вывода mov eax, [rc.bottom] sub eax, 4 mov [(RECT ptr [edi]).bottom], eax ;высота области вывода mov esi, [pSizeBMP] ;адрес POINT m2m [(POINT ptr [esi]).x], [BMap.bmWidth] ;ширина картинки m2m [(POINT ptr [esi]).y], [BMap.bmHeight] ;высота картинки ;все последующее для перерасчета размера области вывода, чтобы картинка ; пропорционально масштабировалась, т.е. пропорционально растягивалась/сжималась ; до ближайшей стороны области вывода. ;Если убрать, то картинка будет растягиваться/сжиматься в области непропорционально mov eax, [(RECT ptr [edi]).right] imul [(POINT ptr [esi]).y] mov ecx, eax mov eax, [(RECT ptr [edi]).bottom] imul [(POINT ptr [esi]).x] cmp eax, ecx jz CSRet jb CSWidth mov eax, ecx idiv [(POINT ptr [esi]).x] mov [(RECT ptr [edi]).bottom], eax jmp CSRet CSWidth: idiv [(POINT ptr [esi]).y] mov [(RECT ptr [edi]).right], eax CSRet: ret CalcSize endp ;загружаем BMP, создаем совместимый контекст, сохраняем эту инфу в структуре окна ;hwnd - описатель окна, куда будем выводить картинку ;szNаme - имя файла SetBmp proc uses esi edi ebx, hwnd:dword, szName:dword xor esi, esi ;совместимый hdc ;загрузим BMP-файл mov edi, rv(LoadImage,0, szName,IMAGE_BITMAP,0,0,LR_LOADFROMFILE) ;получилось? .if edi != 0 ;создадим совместимый контекст mov ebx, rv(GetDC, hwnd) ;описатель контекста нашего окна mov esi, rv(CreateCompatibleDC, ebx);совместимый с ним invoke ReleaseDC, hwnd, ebx ;освободим контекст нашего окна ;если совместимый контекст есть, то выберем в него наш BitMap .if esi != 0 invoke SelectObject, esi, edi ;картинка в совместимом контексте .endif .endif mov ebx, rv(GlobalAlloc, GMEM_FIXED, 8) ;резервируем 8 байт, для 2 dword-ов mov [(BitMapData ptr [ebx]).hBmap], edi ;сохраним hBitMap mov [(BitMapData ptr [ebx]).hMhdc], esi ;совместимый контекст invoke SetWindowLong, hwnd, GWL_USERDATA, ebx ;сохраним адрес структуры в данных окна! ret SetBmp endp ;функция окна BmpWndProc proc uses edi esi,hWin:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD LOCAL Wwd:DWORD, ;ширина основного окна Wht:DWORD, ;высота основного окна ps:PAINTSTRUCT if uMsg == WM_CREATE ;создание окна mov eax, lParam ;адрес структуры с именем файла invoke SetBmp, hWin, [eax] ;подготовимся к выводу ;посчитаем координаты окна, сделаем в центре, по 150 с каждой стороны mov eax, sWid sub eax, 300 mov Wwd, eax mov eax, sHgt sub eax, 300 mov Wht, eax ;переместим окно invoke MoveWindow, hWin, 150, 150, Wwd, Wht, 0 elseif uMsg == WM_SIZE ;пересчитаем размер и положение картинки, исходя из размера окна ;получим адрес структуры из данных окна invoke GetWindowLong,hWin,GWL_USERDATA ;eax=BitMapData ptr mov esi, [(BitMapData ptr [eax]).hBmap] ;esi=hBitMap .if esi != 0 ;посчитаем размеры, если картинка вообще есть invoke CalcSize, esi, hWin, addr rectBMP, addr sizeBMP ;перерисуем invoke InvalidateRect, hWin, 0, 1 .endif elseif uMsg == WM_PAINT ;рисуем BitMap mov edi, rv(BeginPaint,hWin,ADDR ps) ;edi=hDC mov esi, rv(GetWindowLong,hWin,GWL_USERDATA);esi=BitMapData ptr mov esi, [(BitMapData ptr [esi]).hMhdc] ;esi=hMemDC .if esi != 0 ;надо что-то рисовать? ;копируем с масштабированием из совместимого контекста в окно! invoke StretchBlt, edi, [rectBMP.left], [rectBMP.top], [rectBMP.right], [rectBMP.bottom], esi, 0, 0, [sizeBMP.x], [sizeBMP.y], SRCCOPY .endif invoke EndPaint, hWin, ADDR ps else invoke DefWindowProc,hWin,uMsg,wParam,lParam ret endif return 0 BmpWndProc endp end start
Файл ресурсов, исключительно только ради иконки. Задайте любую, какая Вам нравится
rsrc.rc
Код : #include "\masm32\include\resource.h" #define IDI_ICON 500 IDI_ICON ICON MOVEABLE PURE LOADONCALL DISCARDABLE "dialog.ico"
Оценить выпуск | Задать вопрос экспертам главная страница | стать участником | получить консультацию техническая поддержка | восстановить логин/пароль Дорогой читатель! Команда портала RFPRO.RU благодарит Вас за то, что Вы пользуетесь нашими услугами. Вы только что прочли очередной выпуск рассылки. Мы старались. Пожалуйста, оцените его. Если совет помог Вам, если Вам понравился ответ, Вы можете поблагодарить автора - для этого в каждом ответе есть специальные ссылки. Вы можете оставить отзыв о работе портале. Нам очень важно знать Ваше мнение. Вы можете поближе познакомиться с жизнью портала, посетив наш форум, почитав журнал, который издают наши эксперты. Если у Вас есть желание помочь людям, поделиться своими знаниями, Вы можете зарегистрироваться экспертом. Заходите - у нас интересно! МЫ РАБОТАЕМ ДЛЯ ВАС! |
Комментариев нет:
Отправить комментарий