Суббота, 19.07.2025, 14:02 Приветствую Вас Гость

On-line: Книги, учебники, статьи

Главная | Регистрация | Вход | RSS

Глава 5. Разрешение некоторых проблем программирования в Windows(3)

Трансляция программы на Рис. 3.5.2.
MASM32:

 ml /c /coff /DMASM edit.asm
 link /subsystem:windows edit.obj
TASM32:
 tasm32 /ml edit.asm
 tlink32 -aa edit.obj

Разбирая программу, представленную на Рис. 3.2.2, обратите внимание, что представленная схема позволяет делать с окном редактирования практически любые трюки. К примеру. Вы можете заблокировать любой символ, послав вместо него код 0, или вместо одного символа подставить другой и т.д.

IV

В. Возможны ли какие-либо способы взаимодействия и обмен информацией между запущенными приложениями?

Мы уже говорили о различных способах синхронизации, о разделяемой памяти. Есть еще один интересный подход, реализованный в Windows, - это анонимные каналы (pipes)46. Этот подход наиболее эффективен для обмена информацией с консольным процессом, порождаемым данным процессом. Представьте себе, что Вам необходимо, чтобы запускаемый Вами из приложения консольный процесс (например, какой-нибудь строковый компилятор) выводил информацию не в консоль, а в окно редактирования основного процесса. Пример такого приложения представлен на Рис. 3.5.3.

Идея использования каналов очень проста. Канал - как труба: с одной стороны в него втекает информация, а с другой вытекает. Создавая процесс, можно передать ему в качестве дескриптора ввода или вывода соответствующий дескриптор канала. После этого можно обмениваться информацией между двумя процессами при помощи уже известных Вам функций WriteFile и ReadFile.

// файл pipe.rc
// определение констант
#define WS_SYSMENU 0x00080000L
#define WS_VISIBLE 0x10000000L
#define WS_TABSTOP 0x00010000L
#define DS_3DLOOK 0x0004L
#define ES_LEFT 0x0000L
#define WS_CHILD 0x40000000L
#define WS_BORDER 0x00800000L
#define ES_MULTILINE 0x0004L
#define WS_VSCROLL 0x00200000L
#define WS_HSCROLL 0x00100000L

MENUP MENU
{
 POPUP "&Запуск программы"
 {
 MENUITEM "&Запустить", 200
 MENUITEM "Выход из &программы", 300
 }
}

// определение диалогового окна
DIAL1 DIALOG 0, 0, 200, 140
STYLE WS_SYSMENU | DS_3DLOOK
CAPTION "Пример использования PIPE"
FONT 8, "Arial"
{
 CONTROL "", 101, "edit", ES_LEFT | ES_MULTILINE
 | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_HSCROLL, 24, 20, 128, 70
}


; файл pipe.inc
; константы

SW_HIDE equ 0
SW_SHOWNORMAL equ 1
STARTF_USESHOWWINDOW equ 1h
STARTF_USESTDHANDLES equ 100h
STARTF_ADD = STARTF_USESHOWWINDOW + STARTF_USESTDHANDLES

; сообщение приходит при закрытии окна
WM_CLOSE equ 10h
WM_INITDIALOG equ 110h
WM_COMMAND equ 111h
EM_REPLACESEL equ 0C2h

; прототипы внешних процедур
IFDEF MASM
 EXTERN ReadFile@20:NEAR
 EXTERN CloseHandle@4:NEAR
 EXTERN CreatePipe@16:NEAR
 EXTERN SetMenu@8:NEAR
 EXTERN LoadMenuA@8:NEAR
 EXTERN CreateProcessA@40:NEAR
 EXTERN ExitProcess@4:NEAR
 EXTERN GetModuleHandleA@4:NEAR
 EXTERN DialogBoxParamA@20:NEAR
 EXTERN EndDialog@8:NEAR
 EXTERN SendDlgItemMessageA@20:NEAR
ELSE
 EXTERN ReadFile:NEAR
 EXTERN CloseHandle:NEAR
 EXTERN CreatePipe:NEAR
 EXTERN TerminateProcess:NEAR
 EXTERN WaitForSingieObject:NEAR
 EXTERN SetMenu:NEAR
 EXTERN LoadMenuA:NEAR
 EXTERN CreateProcessA:NEAR
 EXTERN ExitProcess:NEAR
 EXTERN GetModuleHandleA:NEAR
 EXTERN DialogBoxParamA:NEAR
 EXTERN EndDialog:NEAR
 EXTERN SendDlgItemMessageA:NEAR

 ReadFile@20 = ReadFile
 CloseHandle@4 = CloseHandle
 CreatePipe@16 = CreatePipe
 TerminateProcess@8 = TerminateProcess
 WaitForSingleObject@8 = WaitForSingleObject
 SetMenu@8 = SetMenu
 LoadMenuA@8 = LoadMenuA
 CreateProcessA@40 = CreateProcessA
 ExitProcess@4 = ExitProcess
 GetModuleHandleA@4 = GetModuleHandleA
 DialogBoxParamA@20 = DialogBoxParamA
 EndDialog@8 = EndDialog
 SendDlgItemMessageA@20 = SendDlgItemMessageA
ENDIF


; структуры
; структура сообщения
MSGSTRUCT STRUC
 MSHWND DD ?
 MSMESSAGE DD ?
 MSWPARAM DD ?
 MSLPARAM DD ?
 MSTIME DD ?
 MSPT DD ?
MSGSTRUCT ENDS

; структура для CreateProcess
STARTUP STRUC
 cb DD 0
 lpReserved DD 0
 lpDesktop DD 0
 lpTitle DD 0
 dwX DD 0
 dwY DD 0
 dwXSize DD 0
 dwYSize DD 0
 dwXCountChars DD 0
 dwYCountChars DD 0
 dwFillAttribute DD 0
 dwFlags DD 0
 wShowWindow DW 0
 cbReserved2 DW 0
 lpReserved2 DD 0
 hStdInput DD 0
 hStdOutput DD 0
 hStdError DD 0
STARTUP ENDS

; структура - информация о процессе
PROCINF STRUC
 hProcess DD ?
 hThread DD ?
 Idproc DD ?
 idThr DD ?
PROCINF ENDS

; файл pipe.asm
.386P
; плоская модель
.MODEL FLAT, stdcall
include pipe.inc
; директивы компоновщику для подключения библиотек
IFDEF MASM
 includelib c:\masm32\lib\user32.lib
 includelib c:\masm32\lib\kernel32.lib
ELSE
 includelib c:\tasm32\lib\import32.lib
ENDIF
;----------------------------------------
; сегмент данных
_DATA SEGMENT DWORD PUBLIC USE32 'DATA'
 STRUP STARTUP <?>
 INF PROCINF <?>
 MSG MSGSTRUCT <?>
 HINST DD 0 ; дескриптор приложения
 PA DB "DIAL1",0
 CMD DB "c:\tasm32\bin\tlink32.exe",0
 PMENU DB "MENUP",0
 HW DD ?
 HR DD ?
 BUFER DB 3000 DUP (0)
 BYT DD ?
_DATA ENDS

; сегмент кода
_TEXT SEGMENT DWORD PUBLIC USE32 'CODE'
START:
; получить дескриптор приложения
 PUSH 0
 CALL GetModuleHandleA@4
 MOV [HINST], EAX
;-------------------------------------------
 PUSH 0
 PUSH OFFSET WNDPROC
 PUSH 0
 PUSH OFFSET PA
 PUSH [HINST]
 CALL DialogBoxParamA@20
 CMP EAX,-1
 JNE KOL
; сообщение об ошибке
KOL:
;---------------------------------
 PUSH 0
 CALL ExitProcess@4
;---------------------------------
; процедура окна
; расположение параметров в стеке
; [EBP+014Н] ; LPARAM
; [EBP+10Н] ; WAPARAM
; [EBP+0CH] ; MES
; [EBP+8] ; HWND
WNDPROC PROC
 PUSH EBP
 MOV EBP,ESP
 PUSH EBX
 PUSH ESI
 PUSH EDI
;------------------------
 CMP DWORD PTR [EBP+0CH],WM_CLOSE
 JNE L1
L3:
 PUSH 0
 PUSH DWORD PTR [EBP+08H]
 CALL EndDialog@8
 JMP FINISH
L1:
 CMP DWORD PTR [EBP+0CH],WM_INITDIALOG
 JNE L2
; загрузить меню
 PUSH OFFSET PMENU
 PUSH [HINST]
 CALL LoadMenuA@8
; установить меню
 PUSH EAX
 PUSH DWORD PTR [EBP+08H]
 CALL SetMenu@8
 JMP FINISH
L2:
 CMP DWORD PTR [EBP+0CH],WM_COMMAND
 JNE FINISH
 CMP WORD PTR [EBP+10H],300
 JE L3
 CMP WORD PTR [EBP+10H],200
 JNE FINISH
; здесь запуск
; в начале PIPE
 PUSH 0
 PUSH 0
 PUSH OFFSET HW
 PUSH OFFSET HR
 CALL CreatePipe@16
 MOV EAX,HW
; здесь запуск консольного приложения
 MOV STRUP.cb,68
 MOV STRUP.lpReserved,0
 MOV STRUP.lpDesktop,0
 MOV STRUP.lpTitle,0
 MOV STRUP.dwFlags,STARTF_ADD
 MOV STRUP.cbReserved2,0
 MOV STRUP.lpReserved2,0
 MOV STRUP.wShowWindow,SW_HIDE ; окно процесса невидимо
 MOV STRUP.hStdOutput,EAX
 MOV STRUP.hStdError,EAX
;----------------------------------------------------------
 PUSH OFFSET INF
 PUSH OFFSET STRUP
 PUSH 0
 PUSH 0
 PUSH 0
 PUSH 1 ; наследует дескрипторы
 PUSH 0
 PUSH 0
 PUSH OFFSET CMD
 PUSH 0
 CALL CreateProcessA@40
; здесь чтение информации
 PUSH 0
 PUSH OFFSET BYT
 PUSH 3000
 PUSH OFFSET BUFER
 PUSH HR
 CALL ReadFile@20
 PUSH OFFSET BUFER
 PUSH 0
 PUSH EM_REPLACESEL
 PUSH 101
 PUSH DWORD PTR [EBP+08H]
 CALL SendDlgItemMessageA@20
; закрыть HANDLE на запись
 PUSH HW
 CALL CloseHandle@4
; закрыть HANDLE на чтение
 PUSH HR
 CALL CloseHandle@4
FINISH:
 MOV EAX,0
 POP EDI
 POP ESI
 POP EBX
 POP EBP
 RET 16
WNDPROC ENDP
_TEXT ENDS
END START
Вход на сайт
Поиск
Календарь
«  Июль 2025  »
ПнВтСрЧтПтСбВс
 123456
78910111213
14151617181920
21222324252627
28293031
Архив записей
Наш опрос
Как Вам удобнее??
Всего ответов: 341
Мини-чат
Друзья сайта
  • Официальный блог
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz
  • Статистика

    Онлайн всего: 1
    Гостей: 1
    Пользователей: 0