Хостинг портала RFpro.ru: Московский хостер Профессиональный хостинг на базе Linux x64 и Windows x64 РАССЫЛКИ ПОРТАЛА RFPRO.RU Чемпионы рейтинга экспертов в этой рассылке Номер выпуска: | 1318 | Дата выхода: | 02.04.2010, 20:00 | Администратор рассылки: | Лысков Игорь Витальевич, Модератор | Подписчиков / экспертов: | 416 / 71 | Вопросов / ответов: | 1 / 1 | IRC-канал по теме: | #assembler | Вопрос № 177425: Добрового времени суток! Нужна помощь в написании программы. Задание: разработать на ассемблере простую программу, содержащую переключаемые страницы (достаточно двух) на одну поставить поле Memo, на вторую организовать вывод в ко... Вопрос № 177425: Добрового времени суток! Нужна помощь в написании программы.
Задание: разработать на ассемблере простую программу, содержащую переключаемые страницы (достаточно двух) на одну поставить поле Memo, на вторую организовать вывод в контейнер точечного рисунка из файла. На каждой странице по нажатию правой кнопки появляется контекстное меню. Команды меню - открытие соответствующих файлов. Нужно выполнить на Microsoft ASM Отправлен: 23.03.2010, 23:46 Вопрос задал: Klayd, Посетитель Всего ответов: 1 Страница вопроса » Отвечает Лысков Игорь Витальевич, Модератор : Здравствуйте, Klayd. Измененная программа вместе с файлом ресурсов с учетом новых требований Все остальное в прикрепленном архиве.
Код: .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\Comctl32.inc include \masm32\include\comdlg32.inc include \masm32\include\shell32.inc include \masm32\include \oleaut32.inc include \masm32\include\msvcrt.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\Comctl32.lib includelib \masm32\lib\comdlg32.lib includelib \masm32\lib\shell32.lib includelib \masm32\lib\oleaut32.lib includelib \masm32\lib\msvcrt.lib
; Прототипы функций WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD TopXY PROTO :DWORD,:DWORD RegisterWinClass PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD MsgLoop PROTO Main PROTO GetFileName PROTO :DWORD,:DWORD,:DWORD,:DWORD CalcSize PROTO :DWORD,:DWORD,:DWORD,:DWORD KeyProcEdit PROTO :DWORD,:DWORD,:DWORD,:DWORD SaveFile PROTO :DWORD
;коды используемых ресурсов IDI_ICON equ 500 I DD_DLG1 equ 101 IDD_DLG2 equ 102 IDM_FILE equ 201 IDM_SAVE equ 202 IDC_TEXT equ 301 IDC_FILENAME equ 302
;флаг задания пиктограммы для propertysheet ; (в windows.inc флаг почему-то называется PSH_USEDWORD ...) PSH_USEHICON equ 00000002h
.data
fChange dd 0 ;флаг изменения текста в редакторе szHeader db 'Property',0 ;заголовок основного окна szTextTXT db 'Файл TXT',0 ;строка меню для выбора текстового файла szTextBMP db 'Файл BMP',0 ;строка меню для выбора графического файла szFilterTXT db 'Текстовые Файлы (*.txt)',0,'*.txt',0,0 ;фильтр для выбора текстовых файлов szFilterBMP db 'Графические Файлы (*.bmp)',0,'*.bmp',0,0;фильтр для выбора графическых файлов szTitle db 'Введите имя открываемого файла',0 ;заголовок для диалога выбора файлов szTitleSave db 'Введите имя сохраняемого файла',0 ;заголовок для диалога выбора файлов szSave db 'Сохранить',0 ;пункт меню, если возможно сохранение szMessage db "Файл изменен, сохранить?",0 ;сообщение, когда было изменение szDefault db 'default.txt',0 ;имя файла по-умолчанию
.data?
hInstance dd ? ;описатель экземпляра процесса CommandLine dd ? ;командная строка hIcon dd ? ;описатель пиктограммы hCursor dd ? ;описатель курсора sWid dd ? ;ширина экрана sHgt dd ? ;высота экрана hWnd dd ? ;описатель главного окна приложения hBitMap dd ? ;описатель растрового изображения hMemDC dd ? ;описатель совместимого контекста устройства (DC) pKeyDefProcEdit dd ? ;адрес предыдущей функции окна редактора PSHeader PROPSHEETHEADERA <> ;заголовок PropertySheet PSPages PROPSHEETPAGE <> ;страницы PropertySheet PROPSHEETPAGE <> rectBMP RECT <> ;координаты для вывода BMP в окне sizeBMP POINT <> ;размер BMP szNameTXT db 256 dup ( ?) ;для хранения текущего имени txt-файла szNameBMP db 256 dup (?) ;для хранения текущего имени bmp-файла
.code
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 ;завершаем процесс
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
Main proc
LOCAL Wwd:DWORD, \ ;ширина основного окна Wht:DWORD, \ ;высота основного окна Wtx:DWORD, \ ;X-координата начала окна Wty:DWORD ;Y-координата начала окна
STRING szClassName,"PropertyDialog_Class" ;класс основного окна
invoke RegisterWinClass,ADDR WndProc,ADDR szClassName, ;регистрируем класс окна hIcon,hCursor,COLOR_BTNFACE+1 ;посчитаем координаты окна mov Wwd, 300 mov Wht, 246 invoke TopXY,Wwd,sWid mov Wtx, eax invoke TopXY,Wht,sHgt mov Wty, eax
;создаем основное окно invoke CreateWindowEx,WS_EX_LEFT, ADDR szClassName, ADDR szHeader, WS_CAPTION or WS_SYSMENU or WS_THICKFRAME or WS_MINIMIZEBOX, Wtx,Wty,Wwd,Wht, NULL,NULL, hInstance,NULL mov hWnd,eax ;сохраним описатель окна
invoke ShowWindow,hWnd, SW_SHOWNORMAL ;показать invoke UpdateWindow,hWnd ;обновить
call MsgLoop ;основной цикл обработки сообщений ret
Main endp
;регистрируем класс окна RegisterWinClass proc lpWndProc:DWORD, lpClassName:DWORD, Icon:DWORD, Cursor:DWORD, bCol or:DWORD
LOCAL wc:WNDCLASSEX
mov wc.cbSize, sizeof WNDCLASSEX mov wc.style, CS_BYTEALIGNCLIENT or \ CS_BYTEALIGNWINDOW m2m wc.lpfnWndProc, lpWndProc mov wc.cbClsExtra, NULL mov wc.cbWndExtra, NULL 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
LOCAL msg:MSG
xor edi, edi ; clear EDI lea esi, msg ; Structure address in ESI jmp jumpin
StartLoop: invoke TranslateMessage, esi invoke DispatchMessage, esi jumpin: invoke GetMessage,esi,edi,edi,edi test eax, eax jnz StartLoop
mov eax, msg.wParam ret
MsgLoop endp
;функция основного окна WndProc proc hWin:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
Switch uMsg Case WM_CREATE call Properties ;создаем PropertySheet ;дальше пойдем только когда выйдем из propertysheet invoke SendMessage,[hWin],WM_CLOSE,0,0 ;и сразу завершаемся return 0
Case WM_DESTROY .if [hMemDC] != 0 invoke DeleteDC, [hMemDC] ;освободим ресурсы, если надо .endif invoke PostQuitMessage,NULL return 0
Endsw
invoke DefWindowProc,hWin,uMsg,wParam,lParam ret
WndProc endp
;вычисляем координату начала отрезка длины wDim, чтобы он был посередине отрезка длины sDim TopXY proc wDim:DWORD, sDim:DWORD
mov eax, [esp+8] sub eax, [esp+4] shr eax, 1
ret 8
TopXY endp
;функция окна первого диалога pPropertySheet PSDialog1 proc uses ebx esi edi, hwnd, uMsg, wParam, lParam LOCAL po int:POINT, \ ;для вывода меню dwCount:dword, \ ;младшее двойное слово длины файла dwHigh:dword ;старшее двойное слово длины файла mov eax, [uMsg] cmp eax, WM_INITDIALOG jz dlg1_initdialog cmp eax, WM_NOTIFY jz dlg1_notify cmp eax, WM_RBUTTONDOWN jz dlg1_rbuttondown cmp eax, WM_COMMAND jz dlg1_command dlg1_ok: xor eax, eax ret
;в инициализации диалога сделаем subclassing процедуры окна редактора ;это необходимо, чтобы по правой кнопке мыши вызывалось наше меню, а не стандартное для ;редактора. Для этого перенаправим сообщение WM_RBUTTONDOWN родителю! dlg1_initdialog: invoke GetDlgItem, [hwnd], IDC_TEXT ;получим в eax описатель окна редактора ;установим новую функцию окна, с сохранением старой в переменной mov [pKeyDefProcEdit], rv(SetWindowLong, eax, GWL_WNDPROC, offset KeyProcEdit) jmp dlg1_ok
;отработка уведомления dlg1_notify: mov eax, [lParam] cmp [(NMHDR PTR [ eax]).code], PSN_SETACTIVE ;страница стала активной jz SetActive cmp [(NMHDR PTR [eax]).code], PSN_APPLY ;нажата "ОК" jz Apply cmp [(NMHDR PTR [eax]).code], PSN_RESET ;нажата "Отмена" jnz dlg1_ok Reset: ;проверим, были ли изменения в редакторе .if fChange == 1 ;спросим, надо ли сохранять invoke MessageBox, [hwnd], offset szMessage, offset szHeader, MB_YESNO .if eax == IDYES ;если "да", то сохраняем invoke SaveFile, [hwnd] .endif .endif jmp dlg1_ok Apply: ;проверим, были ли изменения в редакторе .if fChange == 1 ;сохраним invoke SaveFile, [hwnd] .endif jmp dlg1_ok ;стали активными - запомним себя, как стартовую страницу SetActive: xor eax, eax ;номер нашей страницы mov [PSHeader.nStartPage], eax jmp dlg1_ok
;нажата правая кнопка мыши dlg1_rbuttondown: ;формируем координаты точки, где выводить меню movzx eax, word ptr l Param mov [point.x], eax movzx eax, word ptr lParam+2 sub eax, 14 ; чтобы было чуть выше mov [point.y], eax lea eax, point invoke ClientToScreen,[hwnd], eax ;оконные координаты в экранные mov ebx, rv(CreatePopupMenu) ;создаем меню ;добавляем пункт меню "файл TXT" invoke AppendMenu, ebx, MF_ENABLED or MF_BYCOMMAND, IDM_FILE, offset szTextTXT ;если были изменения, то добавим еще один пункт: "сохранить" .if [fChange] == 1 invoke AppendMenu, ebx, MF_ENABLED or MF_BYCOMMAND, IDM_SAVE, offset szSave .endif ;выводим и ждем выбор invoke TrackPopupMenu, ebx, TPM_CENTERALIGN or TPM_LEFTBUTTON, [point.x], [point.y], 0, [hwnd], 0 ;уничтожаем меню invoke DestroyMenu, ebx jmp dlg1_ok
;сделан выбор в меню dlg1_command: ;проверим уведомление об изменении в редакторе .if word ptr [wParam+2] == EN_CHANGE mov fChange, 1 ;пометим!
;выбор нового файла .elseif wPara m == IDM_FILE ;проверим, надо ли сохранить старое содержимое ;было ли изменение? .if fChange == 1 ;спросим invoke MessageBox, [hwnd], offset szMessage, offset szHeader, MB_YESNO .if eax == IDYES ;сохраняем старое invoke SaveFile, [hwnd] .endif .endif ;запросим имя TXT-файла invoke GetFileName,offset szNameTXT,offset szFilterTXT,GetOpenFileName,offset szTitle ;что-то ввели? .if eax != 0 ;получим описатель GroupBox-а на странице диалога ("ободок") invoke GetDlgItem, [hwnd], IDC_FILENAME ;выведем полное имя файла с путем invoke SetWindowText, eax, offset szNameTXT ;открываем файл mov ebx, rv(CreateFile,offset szNameTXT,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 GetDlgItem, [hwnd], IDC_TEXT ;и выведем в него invoke SetWindowText, eax, esi ;освободим память invoke GlobalFree, esi .endif
;сохранение файла (содержимое редактора точно изменено) .elseif wParam == IDM_SAVE invoke SaveFile, [hwnd] .endif jmp dlg1_ok PSDialog1 endp
;функция окна второго диалога pPropertySheet PSDialog2 proc uses ebx esi edi, hwnd, uMsg, wParam, lParam LOCAL point:POINT, \ ;для вывода меню ps:PAINTSTRUCT ;для рисования в окне в отработке WM_PAINT
mov eax, [uMsg] cmp eax, WM_NOTIFY jz dlg2_notify cmp eax, WM_RBUTTONDOWN jz dlg2_rbuttondown cmp eax, WM_COMMAND jz dlg2_co mmand cmp eax, WM_PAINT jz dlg2_paint dlg2_ok: xor eax, eax ret
;стали активными - запомним себя, как стартовую страницу dlg2_notify: mov eax, [lParam] cmp [(NMHDR ptr [eax]).code], PSN_SETACTIVE jnz dlg2_ok mov eax, 1 ;номер нашей страницы mov [PSHeader.nStartPage], eax jmp dlg2_ok
;нажата правая кнопка мыши dlg2_rbuttondown: ;формируем координаты точки, где выводить меню movzx eax, word ptr lParam mov [point.x], eax movzx eax, word ptr lParam+2 sub eax, 14 ; чтобы было чуть выше mov [point.y], eax lea eax, point invoke ClientToScreen,[hwnd], eax ;оконные координаты в экранные mov ebx, rv(CreatePopupMenu) ;создаем меню ;добавляем один пункт меню invoke AppendMenu, ebx, MF_ENABLED or MF_BYCOMMAND, IDM_FILE, offset szTextBMP ;выводим и ждем выбор invoke TrackPopupMenu, ebx, TPM_CENTERALIGN or TPM_LEFTBUTTON, [point.x], [point.y], 0, [hwnd], 0 ;уничтожа ем меню invoke DestroyMenu, ebx jmp dlg2_ok
;сделан выбор в меню dlg2_command: ;проверим код пункта меню .if wParam == IDM_FILE ;запросим имя BMP-файла invoke GetFileName,offset szNameBMP,offset szFilterBMP,GetOpenFileName,offset szTitle ;что-то ввели? .if eax != 0 ;получим описатель GroupBox-а на странице диалога ("ободок") invoke GetDlgItem, [hwnd], IDC_FILENAME ;выведем полное имя файла с путем invoke SetWindowText, eax, offset szNameBMP
;загрузим BMP-файл mov hBitMap, rv(LoadImage,0, offset szNameBMP,IMAGE_BITMAP,0,0,LR_LOADFROMFILE) ;получилочь? .if eax != 0 ;посчитаем размеры invoke CalcSize, eax, [hwnd], offset rectBMP, offset sizeBMP ;если не было, то создадим совместимый контекст .if [hMemDC] == 0 mov edi, rv(GetDC, [hwnd]) mov [hMemDC], rv(CreateCompatibleDC,edi) invoke ReleaseDC, [hwnd], edi .endif ;если совместимый конт екст есть, то выберем в него наш BitMap .if [hMemDC] != 0 invoke SelectObject, [hMemDC], [hBitMap] ;описатель больше не нужен invoke DeleteObject, [hBitMap] ;перерисуем invoke InvalidateRect,[hwnd],0,1 .endif .endif .endif .endif jmp dlg2_ok
;рисуем BitMap dlg2_paint: mov edi, rv(BeginPaint,[hwnd],ADDR ps) ;edi=hDC .if [hMemDC] != 0 ;надо что-то рисовать? ;копируем с масштабированием из совместимого контекста в окно invoke StretchBlt, edi, [rectBMP.left], [rectBMP.top], [rectBMP.right], \ [rectBMP.bottom], [hMemDC], 0, 0, [sizeBMP.x], [sizeBMP.y], SRCCOPY .endif invoke EndPaint, [hwnd], ADDR ps jmp dlg2_ok PSDialog2 endp
;считаем размеры и координаты изображения ; все числа подобраны эксперементально (чтобы было более-менее красиво ) CalcSize proc uses edi esi, hBmp:dword, hWin:HWND, pRect BMP:dword, pSizeBMP:dword LOCAL BMap:BITMAP, rc:RECT invoke GetObject, hBmp, size BITMAP, ADDR BMap ;узнаем размер картинки< br> invoke GetClientRect, [hWin], ADDR rc ; и размер окна
mov edi, [pRectBMP] ;адрес RECT mov [(RECT ptr [edi]).left], 14 ;начальный X вывода mov [(RECT ptr [edi]).top], 22 ;начальный Y вывода mov eax, [rc.right] sub eax, 28 mov [(RECT ptr [edi]).right], eax ;ширина области вывода mov eax, [rc.bottom] sub eax, 42 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, [(REC T 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
;создание PropertySheet Properties proc uses ebx ;заполняем структуры xor eax, eax mov edx, [hWnd] mov ebx, [hInstance] lea ecx, PSPages mov [PSHeader.dwSize], size PROPSHEETHEADERA mov [PSHeader.dwFlags], PSH_NOAPPLYNOW+PSH_PROPSHEETPAGE+PSH_USEHICON mov [PSHeader.hwndParent], edx mov [PSHeader.hInstance], ebx m2m [PSHeader.hIcon], [hIcon] ;пиктограмма mov [PSHeader.pszCaption], offset szHeader ;заголовок mov [PSHeader.nPages], 2 ;2 страницы mov [PSHeader.nStartPage], eax ;стартовая - первая mov [PSHeader.ppsp], ecx mov [PSHeader.pfnCallback], eax mov [PSHeader.hbmWatermark], eax mov [P SHeader.hplWatermark], eax mov [PSHeader.hbmHeader], eax
mov [(PROPSHEETPAGE ptr [ecx]).dwSize], size PROPSHEETPAGE mov [(PROPSHEETPAGE ptr [ecx]).dwFlags], PSP_DEFAULT + PSP_HIDEHEADER mov [(PROPSHEETPAGE ptr [ecx]).hInstance], ebx mov [(PROPSHEETPAGE ptr [ecx]).pResource], IDD_DLG1 ;имя диалога в ресурсах mov [(PROPSHEETPAGE ptr [ecx]).hIcon], eax mov [(PROPSHEETPAGE ptr [ecx]).pszTitle], eax mov [(PROPSHEETPAGE ptr [ecx]).pfnDlgProc], PSDialog1;функция окна mov [(PROPSHEETPAGE ptr [ecx]).lParam], eax mov [(PROPSHEETPAGE ptr [ecx]).pfnCallback], eax mov [(PROPSHEETPAGE ptr [ecx]).pcRefParent], eax
add ecx, size PROPSHEETPAGE mov [(PROPSHEETPAGE ptr [ecx]).dwSize], size PROPSHEETPAGE mov [(PROPSHEETPAGE ptr [ecx]).dwFlags], PSP_DEFAULT + PSP_HIDEHEADER mov [(PROPSHEETPAGE ptr [ecx]).hInstance], ebx mov [(PROPSHEETPAGE ptr [ecx]).pResource], IDD_DLG2 ;имя диалога в ресурсах mov [(PROPSHEETPAGE ptr [e cx]).hIcon], eax mov [(PROPSHEETPAGE ptr [ecx]).pszTitle], eax mov [(PROPSHEETPAGE ptr [ecx]).pfnDlgProc], PSDialog2;функция окна mov [(PROPSHEETPAGE ptr [ecx]).lParam], eax mov [(PROPSHEETPAGE ptr [ecx]).pfnCallback], eax mov [(PROPSHEETPAGE ptr [ecx]).pcRefParent], eax
invoke PropertySheet, addr PSHeader ;создаем и "сидим" в нем, пока не выйдем
ret Properties endp
;вводим имя файла ;универсальная, как для вызова как GetOpenFileName, так и GetSaveFileName GetFileName proc uses edi, pFName:dword, \ ;имя текущего файла pFilter:dword,\ ;фильтр fun:dword, \ ;функция, которая вызывается pTitle:dword ;заголовок диалога LOCAL ofn:OPENFILENAMEA
STRING szCurrPath,"." ;начальный путь - текущая папка lea edi, ofn mov ecx, (size OPENFILENAMEA) / 4 xor eax, eax rep stosd lea eax, [ofn] mov [(OPENFILENAMEA ptr [eax]).lStructSize], size OPENFILE NAMEA m2m [(OPENFILENAMEA ptr [eax]).lpstrFile], pFName ;имя текущего файла mov [(OPENFILENAMEA ptr [eax]).nMaxFile], 256 ;его м акс длина m2m [(OPENFILENAMEA ptr [eax]).lpstrFilter], pFilter ;фильтр m2m [(OPENFILENAMEA ptr [eax]).lpstrTitle], pTitle ;заголовок диалога mov [(OPENFILENAMEA ptr [eax]).lpstrInitialDir], offset szCurrPath ;текущий путь mov [(OPENFILENAMEA ptr [eax]).Flags], OFN_PATHMUSTEXIST or OFN_FILEMUSTEXIST or OFN_HIDEREADONLY push eax ;параметр - адрес структуры mov eax, [fun] ;адрес функции call dword ptr eax ;вызываем ret GetFileName endp
;сохранение файла SaveFile proc uses edi esi ebx, hwnd:DWORD local dwHiLen:dword ;для старшего dword-а длины ;запросим имя TXT-файла ;проверим, было ли введено имя файла .if [szNameTXT] == 0 ;первый байт == 0? lea edi, [szDefault] ;если да, то берем имя файла по-умолчанию .else lea edi, [szNameTXT] .endif ;ждем имя файла для записи invoke GetFileName,edi,offset szFilterTXT,GetSaveFileName,offset szTitleSave ;что-то ввели? .if eax != 0 pu sh edi ;сохраним имя файла ;получим описатель Edit-а на странице диалога mov edi, rv(GetDlgItem, [hwnd], IDC_TEXT) ;edi - описатель окна редактора mov ebx, rv(GetWindowTextLength, edi) ;ebx - длина содержимого inc ebx ;учтем завершающий 0 mov esi, rv(GlobalAlloc, GMEM_FIXED, ebx) ;esi - адрес памяти под данные invoke GetWindowText, edi, esi, ebx ;получим данные pop edi ;edi - имя файла ;создаем файл на запись со сбросом в 0, если он уже был mov edi, rv(CreateFile,edi,GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0) ;в edi - описатель открытого файла dec ebx ;последний 0 не пишем ;пишем файл invoke WriteFile, edi, esi, ebx, ADDR dwHiLen, 0
invoke CloseHandle, edi ;закрываем файл invoke GlobalFree, esi ;освобождаем память mov fChange, 0 ;сбросим флаг изменения .endif ret SaveFile endp
;новая функция окна для редактора KeyProcEdit proc hwnd:dword, message:dword, wParam:dword, lParam:dword ;отрабатываем только правую кнопку мыши .if message == WM_RBUTTONDOWN ;чуть-чуть подправим позицию курсора, чтобы совпало с тем, что вне редактора (экспериментально) add [lParam], 140010h ;получим родителя редактора invoke GetParent, [hwnd] ;перенаправим ему сообщение invoke SendMessage, eax, message, wParam, lParam xor eax, eax .else ;все остальное не трогаем invoke CallWindowProc, pKeyDefProcEdit, [hwnd],[message], [wParam], [lParam] .endif ret KeyProcEdit endp
end start
Файл ресурсов rsrc.rcКод: #include "\masm32\include\resource.h"
#define IDI_ICON 500 #define IDD_DLG1 101 #define IDD_DLG2 102 #define IDC_TEXT 301 #define IDC_FILENAME 302 #define IDC_STATIC -1 IDI_ICON ICON MOVEABLE PURE LOADONCALL DISCARDABLE "property.ico"
IDD_DLG1 DIALOG 0, 0, 300, 246 STYLE WS_POPUP | WS_CAPTION CAPTION "Text" FONT 8, "MS Sans Serif" BEGIN GROUPBOX "", IDC_FILENAME, 6, 4, 288, 234 EDITTEXT IDC_TEXT,10,12,280,222,WS_VSCROLL | WS_HSCROLL | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE | ES_WANTRETURN | NOT WS_BORDER, WS_EX_STATICEDGE END
IDD_DLG2 DIALOG 0, 00, 300, 246 STYLE WS_POPUP | WS_CAPTION CAPTION "BitMap" FONT 8, "MS Sans Serif" BEGIN GROUPBOX "", IDC_FILENAME, 6, 4, 288, 234 END
Прикрепленный файл: загрузить »
----- Удачи! Ответ отправил: Лысков Игорь Витальевич, Модератор Ответ отправлен: 31.03.2010, 16:25 Номер ответа: 260497 Украина, Кировоград Тел.: +380957525051 ICQ # 234137952 Mail.ru-агент: igorlyskov@mail.ru Абонент Skype: igorlyskov Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"? | Отправить SMS #thank 260497 на номер 1151 (Россия) | Еще номера » | Оценить выпуск » Нам очень важно Ваше мнение об этом выпуске рассылки! Скажите "спасибо" эксперту, который помог Вам! Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА на короткий номер 1151 (Россия) Номер ответа и конкретный текст СМС указан внизу каждого ответа. Полный список номеров » * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов) ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются. *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании. |
Комментариев нет:
Отправить комментарий