Консультация № 178366
13.05.2010, 15:37
43.65 руб.
0 4 1
Здравствуйте! Нужна помощь в написании программы/ Задание: Организовать набор текста в окне и затем его сохранения в файл по выходу из программы. Команды выполняются по нажатию кнопок с пиктограммами на окне типа Toll Bar. 32 битная система..на XP. на MASM. заранее благодарен..

Обсуждение

давно
Посетитель
7438
7205
13.05.2010, 16:07
общий
Angel1731:
Т.е. требуется простенький редактор под Windows?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
13.05.2010, 16:54
общий
да
давно
Посетитель
7438
7205
16.05.2010, 03:48
общий
это ответ
Здравствуйте, Angel1731.
Вот Вам редактор:
Код:

.386
.model flat, stdcall ; 32 bit memory model
option casemap :none ; case sensitive

;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

;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

;=================
; Прототипы функций
;=================
WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
TopXY PROTO :DWORD,:DWORD
Paint_Proc PROTO :DWORD,:DWORD
EditML PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD
Read_File_In PROTO :DWORD,:DWORD
Confirmation PROTO :DWORD
Write_2_Disk PROTO :DWORD
SaveFileAs PROTO
SaveFile PROTO
WordWrap PROTO
EditProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
About PROTO
GetFileName PROTO :DWORD, :DWORD, :DWORD
SaveFileName PROTO :DWORD, :DWORD, :DWORD
Do_ToolBar PROTO :DWORD
SetBmpColor PROTO :DWORD
Do_Status PROTO :DWORD

;=============
; Макро
;=============
;макро для формирования строки в коде
szText MACRO Name, Text:VARARG
LOCAL lbl
jmp lbl
Name db Text,0
lbl:
ENDM

;макро для копирования из переменной в переменную через стек
m2m MACRO M1, M2
push M2
pop M1
ENDM

;макро для выхода из функции с результатом в EAX
return MACRO arg
mov eax, arg
ret
ENDM

;макро для toolbar-а
;дополнительные данные для структуры TBBUTTON
TBextraData MACRO
mov tbb.fsState, TBSTATE_ENABLED
mov tbb.dwData, 0
mov tbb.iString, 0
ENDM

;макро для добавления кнопки
TBbutton MACRO bID, cID
mov tbb.iBitmap, bID ;; button ID number
mov tbb.idCommand, cID ;; command ID number
mov tbb.fsStyle, TBSTYLE_BUTTON
invoke SendMessage, hToolBar, TB_ADDBUTTONS, 1, ADDR tbb
ENDM

;макро для добавления разделителя
TBblank MACRO
mov tbb.iBitmap, 0
mov tbb.idCommand, 0
mov tbb.fsStyle, TBSTYLE_SEP
invoke SendMessage, hToolBar, TB_ADDBUTTONS, 1, ADDR tbb
ENDM

;создание toolbar-а
Create_Tool_Bar MACRO Wd, Ht

szText tbClass, "ToolbarWindow32" ;;имя класса toolbar-а

invoke CreateWindowEx, 0,
ADDR tbClass,
ADDR szDisplayName,
WS_CHILD or WS_VISIBLE,
0, 0, 500, 40,
hWin, NULL,
hInstance, NULL
mov hToolBar, eax ;;сохраним handle

;;задаем размер струкруры TBBUTTON
invoke SendMessage, hToolBar, TB_BUTTONSTRUCTSIZE, sizeof TBBUTTON,0

;;указываем размер bitmap-а, для этого сформируем DWORD с размером
mov ecx, Wd ;; loword = bitmap Width
mov eax, Ht ;; hiword = bitmap Height
shl eax, 16
mov ax, cx
mov bSize, eax
invoke SendMessage, hToolBar, TB_SETBITMAPSIZE, 0, bSize

;;подправим цвет bitmap-а
invoke SetBmpColor, hTbBmp
mov hTbBmp, eax ;;handle Bmp

;;добавляем bitmap в toolbar
mov tbab.hInst, 0
m2m tbab.nID, hTbBmp
invoke SendMessage, hToolBar, TB_ADDBITMAP, 10, ADDR tbab

;размер кнопки такой же, как и bitmap-а
invoke SendMessage, hToolBar, TB_SETBUTTONSIZE, 0, bSize
ENDM

.data
CommandLine dd 0 ;адрес командной строки
hWnd dd 0 ;handle основного окна
hInstance dd 0 ;экземпляр
hIcon dd 0 ;handle пиктограммки
hEdit dd 0 ;handle окна редактора
WrapFlag dd 0 ;флаг переноса строк
lpEditProc dd 0 ;адрес предыдущей функции окна редактора
hStatus dd 0 ;handle статуса
hTbBmp dd 0 ;handle BitMap-а
hToolBar dd 0 ;handle ToolBar-а
szDisplayName db "QEdit",0 ;заголовок программы
szUntitled db "Untitled",0 ;имя файла по-умолчанию
szOpenedAt db "Прочитано ",0 ;сообщение о длине прочитанного файла
szSavedAt db "Записано ",0 ;сообщение о длине записанного файла
bytes db " байт",0 ;конец сообщений о длине файла

WrapON db " Wrap ON",0 ;режим Wrap (перенос строк) включен
WrapOFF db " Wrap OFF",0 ; выключен

szTitleO db "Открыть файл",0;заголовок окна выбора файла для чтения
szTitleS db "Сохранить файл как",0 ;для сохранения
szFilter db "Все файлы",0,"*.*",0, ;маска файлов для выбора
"Текстовые файлы (*.TXT)",0,"*.TXT",0,0

ofn OPENFILENAME <> ;структура для открытия файла
szFileName db 260 dup(0) ;буфер для имени файла

.code
start: ;точка входа
invoke GetModuleHandle, NULL
mov hInstance, eax ;handle экземпляра

invoke GetCommandLine
mov CommandLine, eax ;строка параметров

invoke InitCommonControls ;подгружаем библиотеку comctl32.dll

;стандартный вызов GUI-программ
invoke WinMain, hInstance, NULL, CommandLine, SW_SHOWDEFAULT
invoke ExitProcess,eax ;завершение

WinMain proc hInst :DWORD,
hPrevInst :DWORD,
CmdLine :DWORD,
CmdShow :DWORD

LOCAL wc :WNDCLASSEX ;класс окна
LOCAL msg :MSG ;сообщения
LOCAL Wwd :DWORD ;ширина окна
LOCAL Wht :DWORD ;высота окна
LOCAL Wtx :DWORD ;позиция x вывода на экране
LOCAL Wty :DWORD ;позиция y вывода на экране
LOCAL clBuffer[128] :BYTE ;буфер для параметра


szText szClassName, "QEdit_Class" ;имя класса нашего окна

;заполняем стуктуру wc
mov wc.cbSize, sizeof WNDCLASSEX ;размер
mov wc.style, CS_HREDRAW or CS_VREDRAW or CS_BYTEALIGNWINDOW ;стиль
mov wc.lpfnWndProc, offset WndProc ;функция окна
mov wc.cbClsExtra, NULL ;дополнительные данные класса окна
mov wc.cbWndExtra, NULL ;дополнительные данные для экземпляра окна
m2m wc.hInstance, hInst ;экземпляр программы
invoke GetStockObject, HOLLOW_BRUSH ;пустая кисть для фона
mov wc.hbrBackground, eax ; (все равно перекрывается редактором)
mov wc.lpszMenuName, 600 ;меню из ресурсов
mov wc.lpszClassName, offset szClassName ;имя класса
invoke LoadIcon, hInst, 500 ;icon ID
mov hIcon, eax ;сохраним в hIcon
mov wc.hIcon, eax ;32*32
mov wc.hIconSm, eax ;16*16
invoke LoadCursor, NULL, IDC_ARROW
mov wc.hCursor, eax ;курсор

invoke RegisterClassEx, ADDR wc ;регистрируем класс

mov Wwd, 600 ;ширина окна
mov Wht, 400 ;высота окна

invoke GetSystemMetrics, SM_CXSCREEN ;ширина экрана
invoke TopXY, Wwd, eax
mov Wtx, eax ;позиция x

invoke GetSystemMetrics, SM_CYSCREEN ;высота экрана
invoke TopXY, Wht, eax
mov Wty, eax ;позиция y

invoke CreateWindowEx, 0, ;создаем окно
ADDR szClassName,
ADDR szUntitled,
WS_OVERLAPPEDWINDOW,
Wtx, Wty, Wwd, Wht,
NULL, NULL,
hInst, NULL
mov hWnd, eax ;сохраним handle окна

invoke GetCL, 1, ADDR clBuffer ;читаем первый параметр из командной стоки

.if eax == 1 ;что-то есть?
;считаем именем файла и загружаем в редактор
invoke Read_File_In, ADDR clBuffer, hEdit
.if eax != -1 ;если нет ошибки
; то выводим имя файла в заголовок
invoke SetWindowText, hWnd, ADDR clBuffer
.endif
.endif

invoke ShowWindow, hWnd, SW_SHOWNORMAL ;показываем
invoke UpdateWindow, hWnd ;обновляем

StartLoop: ;цикл обработки сообщений
invoke GetMessage,ADDR msg,NULL,0,0
test eax, eax
jz ExitLoop
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
jmp StartLoop

ExitLoop:
return msg.wParam ;выход
WinMain endp

WndProc proc hWin :DWORD, ;функция окна
uMsg :DWORD,
wParam :DWORD,
lParam :DWORD

LOCAL tbh :DWORD
LOCAL sbh :DWORD
LOCAL wWid :DWORD
LOCAL wHgt :DWORD
LOCAL Rct :RECT
LOCAL tbab :TBADDBITMAP
LOCAL tbb :TBBUTTON

.if uMsg == WM_COMMAND

;команды меню и toolbar-а

;- новый файл ---------------------------
.elseif wParam == 1000
;было ли изменено содержимое редактора
invoke SendMessage, hEdit, EM_GETMODIFY, 0, 0
.if eax == TRUE ;Было?
;спросим, что делать
invoke Confirmation, hWin
.if eax == IDYES
;да - сохраняем и создаем новый файл
invoke SaveFile
.elseif eax == IDCANCEL
;нет - ничего не делаем
xor eax, eax
ret
.endif
.endif

;обнуляем содержимое редактора
invoke SetWindowText, hEdit, NULL
;имя файла по-умолчанию в заголовок
invoke SetWindowText, hWin, ADDR szUntitled
;очищаем поле 2 в статусе
invoke SendMessage, hStatus, SB_SETTEXT, 2, NULL

;- открыть файл -------------------------
.elseif wParam == 1001
;было ли изменено содержимое редактора
invoke SendMessage, hEdit, EM_GETMODIFY, 0, 0
.if eax == TRUE ;Было?
;спросим, что делать
invoke Confirmation, hWin
.if eax == IDYES
;да - сохраняем и открываем файл
invoke SaveFile
.elseif eax == IDCANCEL
;нет - ничего не делаем
xor eax, eax
ret
.endif
.endif

;сбросим имя файла
mov szFileName, 0
;вызываем стандартную функцию для ввола имени файла
invoke GetFileName, hWin, ADDR szTitleO, ADDR szFilter
;что-то ввели?
.if szFileName[0] != 0
;файл загружаем в редактор
invoke Read_File_In, ADDR szFileName, hEdit
;все ок?
.if eax != -1
;выводим имя файда в заголовок окна
invoke SetWindowText, hWin, ADDR szFileName
.endif
.endif

;- сохранить файл с тем же именем ---------
.elseif wParam == 1002
invoke SaveFile ;сохраняем файл

;- сохранить файл с запросом имени (только из меню)
.elseif wParam == 1003
invoke SaveFileAs ;сохраняем файл с запросом имени
.endif

;- выход ---------------------------------
.if wParam == 1010
invoke SendMessage, hWin, WM_SYSCOMMAND, SC_CLOSE, NULL

;- показать диалог about -----------------
.elseif wParam == 1900
invoke About
.endif

;- Undo ----------------------------------
.if wParam == 1100
invoke SendMessage,hEdit,WM_UNDO,0,0

;- Cut -----------------------------------
.elseif wParam == 1101
invoke SendMessage,hEdit,WM_CUT,0,0

;- Copy ----------------------------------
.elseif wParam == 1102
invoke SendMessage,hEdit,WM_COPY,0,0

;- Paste ---------------------------------
.elseif wParam == 1103
invoke SendMessage,hEdit,WM_PASTE,0,0

;- Delete --------------------------------
.elseif wParam == 1104
invoke SendMessage,hEdit,WM_CLEAR,0,0

;- WordWrap ------------------------------
.elseif wParam == 1105 ;Wordwrap
invoke WordWrap

.endif

;====== конец команд меню uMsg=WM_COMMAND ======

;- передача фокуса в редактор --------------------------
.elseif uMsg == WM_SETFOCUS
invoke SetFocus, hEdit

;- при смене системных цветов пересоздать toolbar ------
.elseif uMsg == WM_SYSCOLORCHANGE
invoke Do_ToolBar, hWin

;- создание окна ---------------------------------------
.elseif uMsg == WM_CREATE
invoke Do_ToolBar, hWin ;toolbar
invoke Do_Status,hWin ;статус

mov WrapFlag, 0 ;изначально флаг переноса строк выключен
;создаем редактор
invoke EditML, NULL, 0, 30, 300, 200, hWin, 700, WrapFlag
mov hEdit, eax ;handle редактора

;сабклассинг функции окна редактора
invoke SetWindowLong, hEdit, GWL_WNDPROC, EditProc
mov lpEditProc, eax

;сообщение WrapOFF в статус
invoke SendMessage, hStatus, SB_SETTEXT, 1, ADDR WrapOFF

;- изменение размеров окна -----------------------------
.elseif uMsg == WM_SIZE
;команда toolbar-у подправить свой размер
invoke SendMessage, hToolBar, TB_AUTOSIZE, 0, 0
;та же команда статусу
invoke MoveWindow, hStatus, 0, 0, 0, 0, TRUE

;получим размеры органов управления
invoke GetClientRect, hToolBar, ADDR Rct
m2m tbh, Rct.bottom ;высота toolbar-а

invoke GetClientRect, hStatus, ADDR Rct
m2m sbh, Rct.bottom ;высота statusbar-а

invoke GetClientRect, hWin, ADDR Rct
m2m wWid, Rct.right ;ширина окна
m2m wHgt, Rct.bottom ;высота окна

mov eax, tbh ;отнимем от высоты окна
sub wHgt, eax ;высоту toolbar-а
mov eax, sbh ;и высоту statusbar-а
sub wHgt, eax

;перемещаем редактор
invoke MoveWindow, hEdit, 0, tbh, wWid, wHgt, TRUE

;- закрытие --------------------------------------------
.elseif uMsg == WM_CLOSE
;было ли изменено содержимое редактора
invoke SendMessage, hEdit, EM_GETMODIFY, 0, 0
.if eax == TRUE ;Было?
;спросим, что делать
invoke Confirmation, hWin
.if eax == IDYES
;да - сохраняем и открываем файл
invoke SaveFile
.elseif eax == IDCANCEL
;нет - ничего не делаем
xor eax, eax
ret
.endif
.endif

;- уничтожение -----------------------------------------
.elseif uMsg == WM_DESTROY
invoke PostQuitMessage,NULL
return 0
.endif

;- отработка по-умолчанию ------------------------------
invoke DefWindowProc,hWin,uMsg,wParam,lParam

ret

WndProc endp

;размещаем окно посередине экрана
;wDim - размерность (ширина, высота) окна
;sDim - размерность (ширина, высота) экрана
;получаем в eax начало окна в выбранной размерности
TopXY proc wDim:DWORD, sDim:DWORD

shr sDim, 1 ; экранная размерность пополам
shr wDim, 1 ; оконная размерность пополам
mov eax, wDim ;
sub sDim, eax ; sDim/2 - wDim/2

return sDim ; eax = sDim/2 - wDim/2

TopXY endp

;создаем редактор
EditML proc szMsg:DWORD, tx:DWORD, ty:DWORD, wd:DWORD, ht:DWORD,
hParent:DWORD, ID:DWORD, Wrap:DWORD

LOCAL hCtl :DWORD
LOCAL eStyle :DWORD

;имя класа
szText CtlStyle, "EDIT"

;стиль
mov eStyle, WS_VISIBLE or WS_CHILDWINDOW or \
WS_VSCROLL or ES_NOHIDESEL or \
ES_AUTOVSCROLL or ES_MULTILINE

.if Wrap == 0 ;если нет переноса строк
or eStyle, WS_HSCROLL or ES_AUTOHSCROLL
.endif

;создаем редактор
invoke CreateWindowEx, WS_EX_CLIENTEDGE, ADDR CtlStyle, szMsg,
eStyle, tx, ty, wd, ht, hParent, ID, hInstance, NULL
mov hCtl, eax

;будем использовать шрифт FIXED FONT
invoke GetStockObject, SYSTEM_FIXED_FONT
invoke SendMessage, hCtl, WM_SETFONT, eax, TRUE

return hCtl ;вернем handle редактора

EditML endp

;читаем файл lpszDiskFile в редактор hEditControl
Read_File_In proc lpszDiskFile:DWORD, hEditControl:DWORD

LOCAL hFile :DWORD
LOCAL hMem$ :DWORD
LOCAL ln :DWORD
LOCAL br :DWORD
LOCAL txtBuffer[256] :BYTE
LOCAL sizeBuffer[16] :BYTE

;открываем фацл на чтение
invoke CreateFile, lpszDiskFile, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
mov hFile, eax

.if eax == -1 ;открылся?
;нет - выводим сообщение
szText szMessFile, "Файл '"
szText szMessNotFound, "' не найден"
invoke lstrcpy, ADDR txtBuffer, ADDR szMessFile
invoke lstrcat, ADDR txtBuffer, lpszDiskFile
invoke lstrcat, ADDR txtBuffer, ADDR szMessNotFound
invoke MessageBox, hWnd, ADDR txtBuffer, ADDR szDisplayName, MB_OK
mov eax, -1
ret
.endif
;получим длину файла
invoke GetFileSize, hFile, NULL
mov ln, eax

.if ln > 32767 ;простой edit может принять только 32к символов
;выводим сообщение о слишком длинном файле
invoke CloseHandle, hFile
szText tooBig, "' больше 32767 байт"
invoke lstrcpy, ADDR txtBuffer, ADDR szMessFile
invoke lstrcat, ADDR txtBuffer, lpszDiskFile
invoke lstrcat, ADDR txtBuffer, ADDR tooBig
invoke MessageBox, hWnd, ADDR txtBuffer, ADDR szDisplayName, MB_OK
mov eax, -1
ret
.endif

;выделим память для буфера
invoke SysAllocStringByteLen, 0, ln
mov hMem$, eax ;сохраним адрес буфера

;читаем файл
invoke ReadFile, hFile, hMem$, ln, ADDR br, NULL
;и загоняем в редактор
invoke SetWindowText, hEditControl, hMem$

;освобождаем память
invoke SysFreeString, hMem$
;закрываем файл
invoke CloseHandle, hFile

;сформируем сообщение о длине файла
invoke lstrcpy, ADDR txtBuffer, ADDR szOpenedAt
invoke dwtoa, ln, ADDR sizeBuffer
invoke lstrcat, ADDR txtBuffer, ADDR sizeBuffer
invoke lstrcat, ADDR txtBuffer, ADDR bytes
;выведем его в statusbar-е
invoke SendMessage, hStatus, SB_SETTEXT, 2, ADDR txtBuffer

return br ;вернем длину файла

Read_File_In endp

;запрос подтверждения продолжения, когда в файле есть несохраненные изменения
;вернет в eax MB_YES, MB_NO, MB_CANCEL
Confirmation proc hMain:DWORD

szText ConfirmMsg, "Файл не сохранен, сохранять будете ?"
invoke MessageBox, hMain, ADDR ConfirmMsg, ADDR szDisplayName,
MB_YESNOCANCEL or MB_ICONQUESTION
ret

Confirmation endp

;сохраняем на диск
Write_2_Disk proc lpszFile_Name:DWORD

LOCAL ln :DWORD
LOCAL hMem$ :DWORD
LOCAL hFile :DWORD
LOCAL bw :DWORD
LOCAL txtBuffer[64] :byte
LOCAL sizeBuffer[16] :BYTE

;создаем файд, если такой был, то его длина сбрасывается в 0
invoke CreateFile, lpszFile_Name, ; имя файла
GENERIC_WRITE, ; доступ чтения/записи
NULL, ; режим share
NULL, ; security attributes
CREATE_ALWAYS, ; как создавать
FILE_ATTRIBUTE_NORMAL, ; аттрибуты файла
NULL

mov hFile, eax ;сохраним handle файла

invoke GetWindowTextLength, hEdit ;читаем длину файла
mov ln, eax
inc ln ;+1 байт для завершающего 0

invoke SysAllocStringByteLen, 0, ln ;запрашиваем память
mov hMem$, eax

invoke GetWindowText, hEdit, hMem$, ln ;читаем в буфер содержимое файла

dec ln ;уберем завершающий 0
invoke WriteFile, hFile, hMem$, ln, ADDR bw, NULL ;пишем в файл

invoke SysFreeString, hMem$ ;освобождаем память
invoke CloseHandle, hFile ;закрываем handle файла

;помечаем, что файл не изменялся
invoke SendMessage, hEdit, EM_SETMODIFY, FALSE, 0

;сформируем сообщение о длине файла
invoke lstrcpy, ADDR txtBuffer, ADDR szSavedAt
invoke dwtoa, ln, ADDR sizeBuffer
invoke lstrcat, ADDR txtBuffer, ADDR sizeBuffer
invoke lstrcat, ADDR txtBuffer, ADDR bytes

;выведем его в statusbar-е
invoke SendMessage, hStatus, SB_SETTEXT, 2, ADDR txtBuffer

return bw ;вернем записанную длину

Write_2_Disk endp

;Сохранить как...
SaveFileAs proc
;сбрасываем имя файла
mov szFileName, 0
;запрашиваем имя файла
invoke SaveFileName, hWnd, ADDR szTitleS, ADDR szFilter
;если было введено
.if szFileName != 0 ;0 будет при нажатии на cancel
;сохраняем
invoke Write_2_Disk, ADDR szFileName
;имя файла в заголовок окна
invoke SetWindowText, hWnd, ADDR szFileName
.endif

ret

SaveFileAs endp

;сохранить
SaveFile proc

LOCAL buffer[128]:BYTE

;читаем заголовок (там имя файла)
invoke GetWindowText, hWnd, ADDR buffer, 128

;проверим на имя "Untitled"
invoke lstrcmp, ADDR buffer, ADDR szUntitled
.if eax == 0
invoke SaveFileAs ;если Untitled, то запросим имя,
ret ; вызвав "сохранить как"
.endif

invoke Write_2_Disk, ADDR buffer ;иначе, сохранить с тем же именем

ret

SaveFile endp

;смена режима переноса строк
WordWrap proc

LOCAL mFlag :DWORD
LOCAL ln :DWORD
LOCAL hMem$ :DWORD

invoke SendMessage, hEdit, EM_GETMODIFY, 0, 0
mov mFlag, eax ;сохраним флаг изменения содержимого

invoke GetWindowTextLength, hEdit
mov ln, eax ;длина содержимого
inc ln ;+1 для 0

invoke SysAllocStringByteLen, 0, ln
mov hMem$, eax ;выделим память для буфера
invoke GetWindowText, hEdit, hMem$, ln ;читаем в буфер

invoke DestroyWindow, hEdit ;уничтожаем окно редактора!

;меняем флаг Wrap на противоположный и выводим сообщение в статусе
.if WrapFlag == 0
mov WrapFlag, 1
invoke SendMessage, hStatus, SB_SETTEXT, 1, ADDR WrapON
.elseif WrapFlag == 1
mov WrapFlag, 0
invoke SendMessage, hStatus, SB_SETTEXT, 1, ADDR WrapOFF
.endif

;создаем окно редактора заново с измененным состоянием Wrap
invoke EditML, NULL, 0, 30, 300, 200, hWnd, 700, WrapFlag
mov hEdit, eax

;сабклассинг окна
invoke SetWindowLong, hEdit, GWL_WNDPROC, EditProc
mov lpEditProc, eax

;установим нужное положение и размер
invoke SendMessage, hWnd, WM_SIZE, 0, 0
;восстановим содержимое редактора
invoke SetWindowText, hEdit, hMem$
;освобождаем память буфера
invoke SysFreeString, hMem$
;восстановим состояние флага модификации содержимого
invoke SendMessage, hEdit, EM_SETMODIFY, mFlag, 0
;фокус ввода редактору
invoke SetFocus, hEdit

ret

WordWrap endp

;функция окна редактора при сабклассинге
EditProc proc hCtl :DWORD,
uMsg :DWORD,
wParam :DWORD,
lParam :DWORD

;анализируем коды интересующих нас клавиш
.if uMsg == WM_KEYUP
.if wParam == VK_F1 ;F1 - Abort
invoke About
.elseif wParam == VK_F9 ;F9 - смена Wrap
invoke WordWrap
.elseif wParam == VK_ESCAPE ;Escape - выход
invoke SendMessage, hWnd, WM_SYSCOMMAND, SC_CLOSE, NULL
return 0
.endif
.endif
;все остальное на основную функцию окна редактора
invoke CallWindowProc, lpEditProc, hCtl, uMsg, wParam, lParam

ret

EditProc endp

;about
About proc

;заголовок
szText AboutMsg, "QEdit Text Editor"
;стандартная функция вывода About
invoke ShellAbout, hWnd, ADDR szDisplayName, ADDR AboutMsg, hIcon

ret

About endp

;создание toolbar-а
Do_ToolBar proc hWin:DWORD
LOCAL bSize :DWORD
LOCAL tbab :TBADDBITMAP
LOCAL tbb :TBBUTTON

;загружаем bitmap для toolbar-а
invoke LoadBitmap, hInstance, 750
mov hTbBmp, eax

;создадим toolbar с кнопками 18х18
Create_Tool_Bar 18, 18

TBextraData ;дополнительные данные для структуры TBBUTTON

;добавляем кнопки, параметры: индекс картинки в BitMap-е, ID кнопки
TBbutton 4, 1000
TBbutton 5, 1001
TBbutton 6, 1002
TBblank
TBbutton 0, 1101
TBbutton 1, 1102
TBbutton 2, 1103
TBbutton 3, 1100
TBblank
TBbutton 9, 1105
TBblank
TBbutton 7, 1900
TBbutton 8, 1010

ret

Do_ToolBar endp

;подправим цвет BitMap-а
SetBmpColor proc hBitmap:DWORD

LOCAL mDC :DWORD
LOCAL hBrush :DWORD
LOCAL hOldBmp :DWORD
LOCAL hReturn :DWORD
LOCAL hOldBrush :DWORD

invoke CreateCompatibleDC, NULL ;создаем совместимый DC
mov mDC,eax

invoke SelectObject, mDC, hBitmap ;выбираем в mDC картинку,
mov hOldBmp,eax ; старый сохраняем

invoke GetSysColor, COLOR_BTNFACE
invoke CreateSolidBrush, eax
mov hBrush, eax ;создаем кисть с цветом COLOR_BTNFACE

invoke SelectObject, mDC, hBrush ;выбираем
mov hOldBrush, eax ; старую сохраняем

invoke GetPixel, mDC, 1, 1 ;читаем цвет пиксела (1,1)
;закрашиваем все точки, равные цветом с (1,1) кистью COLOR_BTNFACE
invoke ExtFloodFill, mDC, 1, 1, eax, FLOODFILLSURFACE

;восстанавливаем кисть
invoke SelectObject, mDC, hOldBrush
;удаляем созданную кисть
invoke DeleteObject, hBrush
;получим handle BitMap-а, для этого что-то выберем, а вернется нужный нам handle
invoke SelectObject, mDC, hBitmap
mov hReturn, eax ;сохраним
invoke DeleteDC, mDC ;удалим совместимый DC

return hReturn ;возвращаем handle подправленного BitMap-а

SetBmpColor endp

;получение имени файла для чтения, с помощью стандартного диалога
GetFileName proc hParent:DWORD, lpTitle:DWORD, lpFilter:DWORD

mov ofn.lStructSize,sizeof OPENFILENAME
m2m ofn.hWndOwner, hParent
m2m ofn.hInstance, hInstance
m2m ofn.lpstrFilter,lpFilter
m2m ofn.lpstrFile, offset szFileName
mov ofn.nMaxFile, sizeof szFileName
m2m ofn.lpstrTitle, lpTitle
mov ofn.Flags, OFN_EXPLORER or OFN_FILEMUSTEXIST or \
OFN_LONGNAMES

invoke GetOpenFileName, ADDR ofn

ret

GetFileName endp

;получение имени файла для записи, с помощью стандартного диалога
SaveFileName proc hParent:DWORD,lpTitle:DWORD,lpFilter:DWORD

mov ofn.lStructSize,sizeof OPENFILENAME
m2m ofn.hWndOwner, hParent
m2m ofn.hInstance, hInstance
m2m ofn.lpstrFilter,lpFilter
m2m ofn.lpstrFile, offset szFileName
mov ofn.nMaxFile, sizeof szFileName
m2m ofn.lpstrTitle, lpTitle
mov ofn.Flags, OFN_EXPLORER or OFN_LONGNAMES

invoke GetSaveFileName, ADDR ofn

ret

SaveFileName endp

;создание статуса
Do_Status proc hParent:DWORD

LOCAL sbParts[4]:DWORD

;создаем окно статуса
invoke CreateStatusWindow, WS_CHILD or WS_VISIBLE or \
SBS_SIZEGRIP,NULL, hParent, 200
mov hStatus, eax

; sbParts - разбивает на 3 части
mov [sbParts + 0], 125 ; пикселей слева
mov [sbParts + 4], 250 ; -//-
mov [sbParts + 8], -1 ; до конца

invoke SendMessage, hStatus, SB_SETPARTS, 3, ADDR sbParts

ret

Do_Status endp

end start

Ресурсы:
Код:
#include "\masm32\include\resource.h"

1 24 DISCARDABLE "qedit.exe.manifest"

500 ICON MOVEABLE PURE LOADONCALL DISCARDABLE "QEDIT.ICO"

750 BITMAP MOVEABLE PURE LOADONCALL DISCARDABLE "TOOLBAR.BMP"

600 MENUEX MOVEABLE IMPURE LOADONCALL DISCARDABLE
BEGIN
POPUP "&File", , , 0
BEGIN
MENUITEM "&New", 1000
MENUITEM "&Open", 1001
MENUITEM "", , 0x0800 /*MFT_SEPARATOR*/
MENUITEM "&Save", 1002
MENUITEM "Save &As", 1003
MENUITEM "", , 0x0800 /*MFT_SEPARATOR*/
MENUITEM "&Exit", 1010
END
POPUP "&Edit",,,0
BEGIN
MENUITEM "&Undo\tCtrl+Z",1100
MENUITEM "", , 0x0800 /*MFT_SEPARATOR*/
MENUITEM "&Cut\tCtrl+X",1101
MENUITEM "C&opy\tCtrl+C",1102
MENUITEM "&Paste\tCtrl+V",1103
MENUITEM "", , 0x0800 /*MFT_SEPARATOR*/
MENUITEM "&Delete\tDelete",1104
MENUITEM "", , 0x0800 /*MFT_SEPARATOR*/
MENUITEM "&Wordwrap\tF9", 1105
END
POPUP "&Help", , , 0
BEGIN
MENUITEM "&About", 1900
END
END

Весь проект здесь
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
16.05.2010, 15:32
общий
Спасибо!
Форма ответа