Интерфейс DOS-Windows

Использование и разработка софта (преимущественно на ПЦ)

Moderator: Shaos

User avatar
Lavr
Supreme God
Posts: 16682
Joined: 21 Oct 2009 08:08
Location: Россия

Интерфейс DOS-Windows

Post by Lavr »

Вот такая у меня проблема возникла: если приложние MS-DOS работает под Windows в полноэкранном
режиме, можно ли из него послать какое-либо сообщение самой Windows?

То есть, мне надо, чтобы при рабое в полноэкранном режиме по клику мыши (или по двойному клику) это
приложение MS-DOS свернулось.
Как будто в нём нажали [Alt]+[Enter].
iLavr
aav8
Maniac
Posts: 287
Joined: 05 Nov 2008 19:47
Location: 81.28.208.238

Re: Windows 98/Me

Post by aav8 »

Читал давным давно такую книгу
"Руководство программиста по Microsoft Windows 95"
Там было что-то про сервисы Windows для DOS
b2m
Devil
Posts: 907
Joined: 26 May 2003 06:57

Re: Windows 98/Me

Post by b2m »

Многое можно сделать через int 2Fh.
Last edited by b2m on 30 Dec 2019 04:54, edited 4 times in total.
Страничка эмулятора наших компьютеров
http://bashkiria-2m.narod.ru/
User avatar
Lavr
Supreme God
Posts: 16682
Joined: 21 Oct 2009 08:08
Location: Россия

Re: Windows 98/Me

Post by Lavr »

aav8 wrote:...было что-то про сервисы Windows для DOS
Я даже делал "что-то" через сервисы Windows для DOS - я написал резидентный драйвер мыши,
которая в текстовом режиме изображала "графическую стрелку". Но в окне Windows эта стрелка
выглядела как 4 уродских псевдосимвола (это так и есть по сути :wink: ), поэтому я использовал
расширенный сервис INT 4FH, чтобы драйвер мог узнать у Windows - в оконном режиме приложение
DOS, или в полноэкранном.

В данный момент пытаюсь подумать в направлении INT 2FH, кажется. Приложение DOS может, как мне
кажется, послать что-то Windows через Clipboard или спулер печати.

Была у меня еще одна хитрая мысль: из приложения Windows в цикле "слушал" GetAsyncKeyState(VK_RBUTTON).
Под Windows работает четко - в любом приложении правую кнопку мыши "слышит", но полноэкранный
режим приложения DOS клики мыши в Windows не пропускает... :osad:
iLavr
User avatar
Lavr
Supreme God
Posts: 16682
Joined: 21 Oct 2009 08:08
Location: Россия

Re: Windows 98/Me

Post by Lavr »

Пока удачно работает только вот такой трюк:

Приложение Windows запускает приложение DOS в полноэкранном режиме через:
ShellExecute(...)

Приложение Windows ждёт примерно 300...500 mS, чтобы приложение DOS запустилось.

Приложение Windows ищет "хэндлер" окна приложения DOS через имя окна и класс:
FindWindowA(...), класс окна DOS - "tty".

Если "хэндлер" найден, приложение Windows посылает окну приложения DOS:
SetActiveWindow("хэндлер" )

И далее приложение Windows посылает окну приложения DOS::
keybd_event(VK_MENU, 0) - нажали Alt;
keybd_event(VK_RETURN, 0) - нажали Enter;
Пауза 200 mS;
keybd_event(VK_RETURN, KEYEVENTF_KEYUP) - ОТжали Enter;
keybd_event(VK_MENU, KEYEVENTF_KEYUP) - ОТжали Alt;

И приложение DOS великолепно вернулось в оконный режим! :kruto:

Работает также такой вариант - по нажатию кнопки в приложении Windows,
приложение Windows посылает окну приложения DOS:
keybd_event(VK_MENU, 0) - нажали Alt;
keybd_event(VK_RETURN, 0) - нажали Enter;
Пауза 200 mS;
keybd_event(VK_RETURN, KEYEVENTF_KEYUP) - ОТжали Enter;
keybd_event(VK_MENU, KEYEVENTF_KEYUP) - ОТжали Alt;
Пауза 5 секунд!; :wink:
keybd_event(VK_MENU, 0) - нажали Alt;
keybd_event(VK_RETURN, 0) - нажали Enter;
Пауза 200 mS;
keybd_event(VK_RETURN, KEYEVENTF_KEYUP) - ОТжали Enter;
keybd_event(VK_MENU, KEYEVENTF_KEYUP) - ОТжали Alt;

И приложение DOS великолепно разворачивается в полноэкранный режим и через 5 секунд
возвращается в оконный режим! :kruto:

Осталось немного: как-то научиться "просигналить" приложению Windows из полноэкранного режима
приложения DOS... :-?
iLavr
User avatar
Lavr
Supreme God
Posts: 16682
Joined: 21 Oct 2009 08:08
Location: Россия

Re: Windows 98/Me

Post by Lavr »

Вот еще мысль: если в приложении DOS программно "нажать" PrintScreen - оно должно обратиться
к Windows Clipboard или нет? :roll:
iLavr
b2m
Devil
Posts: 907
Joined: 26 May 2003 06:57

Re: Windows 98/Me

Post by b2m »

Послать сообщение WM_USER+100h можно опять-таки через int 2Fh, но если хочется своих костыльных решений, то можно просто создавать/удалять файл в определённом каталоге :)
Last edited by b2m on 30 Dec 2019 04:55, edited 1 time in total.
Страничка эмулятора наших компьютеров
http://bashkiria-2m.narod.ru/
User avatar
Lavr
Supreme God
Posts: 16682
Joined: 21 Oct 2009 08:08
Location: Россия

Re: Windows 98/Me

Post by Lavr »

Проверил, из полноэкранного режима приложения DOS [PrintScreen] и [Alt]+[PrintScreen] при нажатии с клавиатуры работают.
Хотя пол-интернета слёзно пишут, что не работает, но спишем на Windows 98...

Попробую "нажать программно" [PrintScreen] или [Alt]+[PrintScreen] в приложении DOS.

Сообщение WM_USER+100h кому посылать? "Всем окнам"? Или эксплореру?
iLavr
b2m
Devil
Posts: 907
Joined: 26 May 2003 06:57

Re: Windows 98/Me

Post by b2m »

Lavr wrote:кому посылать?
Тому, кого зарегистрируешь. Там как всегда (у мелких и мягких) не всё просто. Поэтому рекомендую всё-таки воспользоваться VSWITCHD.
Страничка эмулятора наших компьютеров
http://bashkiria-2m.narod.ru/
User avatar
Lavr
Supreme God
Posts: 16682
Joined: 21 Oct 2009 08:08
Location: Россия

Re: Windows 98/Me

Post by Lavr »

b2m wrote: Поэтому рекомендую всё-таки воспользоваться VSWITCHD.
Можно небольшой пример "на пальцах"? Ну хотя бы, как я вот тут выше рассказал:
viewtopic.php?f=81&t=9497&start=105#p153084
iLavr
b2m
Devil
Posts: 907
Joined: 26 May 2003 06:57

Re: Windows 98/Me

Post by b2m »

Ишь какой хитрый! :)

Попробовал я, в Win2k нифига не работает. Собственно в инетах об этом тоже пишут.
Походу, чтобы это работало, нужно иметь соответствующий VxD, который и выполнит нужное действо. А где брать этот драйвер - нигде не сказано.

Механизм mov ax,1684h / mov bx,DeviceID / int 2Fh это собственно и есть документированный (легальный) способ связи между ДОС и виндой. DeviceID документируется мелкософтом, но можно, видимо, использовать нечто своё, типа 7FE0h, для своего драйвера, в надежде на то, что оно никогда не совпадёт с реальным.

Так что, как всегда, в инете пишут много, а реально работает из этого - шишь да маленько. Поиски продолжаются...
Страничка эмулятора наших компьютеров
http://bashkiria-2m.narod.ru/
User avatar
Lavr
Supreme God
Posts: 16682
Joined: 21 Oct 2009 08:08
Location: Россия

Re: Windows 98/Me

Post by Lavr »

b2m wrote:Ишь какой хитрый! :)
Нет, я просто умный... :lol:
b2m wrote:Походу, чтобы это работало, нужно иметь соответствующий VxD, который и выполнит нужное действо. А где брать этот драйвер - нигде не сказано.
А я вот про это знал, почему и попросил пример "на пальцах" - интересно было, что посоветует Г.Остер? :ebiggrin:

Чисто к сведению, по хорошему и реально это, в частности, работает вот так:

 Пример работы с VXD И INT 2FH

Code: Select all

;   Для опознания pежимов "полноэкpанный-оконный" под W 9.xx используется
;   VWFD.386 из MS DDK. Она должна находиться в диpектоpии %WINDIR%\SYSTEM\
;   а в файле SYSTEM.INI в pаздел [386Enh] должна быть указана стpока:
;   DEVICE=VWFD.386 - тогда pежимы опознаются коppектно.
;
;==========================================================================
;               SUBROUTINE_TESTWIN - тест pежима окна
;==========================================================================
TESTWIN         PROC    NEAR
;_______________а вот тут мы попытаемся влезть вpоде не мешая...____________
                PUSHF
                PUSH    AX                      ; Сохранить регистры
                PUSH    BX
                PUSH    CX
                PUSH    DX
                PUSH    BP
                PUSH    SI
                PUSH    DI
                PUSH    DS
                PUSH    ES

                CMP     BYTE PTR Api_Exist,0FFH ; is VWFD installed?
                JNE     LOC_EXIT                ; NOT...

;_______________ Каждый pаз пpовеpять это не надо __________________________
;                mov     ax,1684h         ; Get Device API call
;                mov     bx,7FE0h         ; for the VWFD VxD
;                int     2fh              ; do enhanced API
;                mov     WORD PTR Api_Entry,di; save the callback address
;                mov     WORD PTR Api_Entry+2,es
;                mov     ax,es            ; is VWFD installed?
;                or      ax,di
;                jnz     OUR_LOCK         ;
;                MOV     BYTE PTR Api_Exist,00H
;                JMP     LOC_EXIT
;OUR_LOCK:
;                mov     ax,1683h         ; Get Current VM
;                int     2fh              ; do enhanced API
;_________________________________________; BX now contains current VM _____

;_______________спpосим нашу VxD - че как __________________________________
                mov     BX,CS:WORD PTR WIN_VM_ID ; GET current VM
                CALL    DWORD PTR Api_Entry ; call VWFD
                JC      LOC_EXIT            ; Specified VM does not exist.
;                XOR     AX,AX               ; имитация 0FFFFH (отладка)
                OR      AX,AX               ; Z = FULL_SCREEN
                JNZ     LOC_TEST;____________ if AX=0, we're running fullscreen
                mov     AL,CS:BYTE PTR Win_State
                OR      AL,AL               ; а до этого ?
                JZ      LOC_EXIT            ; тоже был 00H
                MOV     AX,0003H            ; 3 - полный экpан - в окно
                mov     CS:BYTE PTR Win_State,00h;('Эмулятор pаботает в полноэкpанном pежиме')
                JMP     SET_WIND
LOC_TEST:;__________________________
                CMP     CS:BYTE PTR Win_State,0ffh;  ('Эмулятор pаботает в оконном pежиме')
                JZ      LOC_EXIT
                MOV     CS:BYTE PTR Win_State,0ffh;  ('Эмулятор pаботает в оконном pежиме')
                MOV     AX,0002H            ; 2 - окно - в полный экpан
SET_WIND:
                CALL    INT_1607            ; включить/погасить куpсоp
LOC_EXIT:
                POP     ES                  ; Восстановить регистры
                POP     DS
                POP     DI
                POP     SI
                POP     BP
                POP     DX
                POP     CX
                POP     BX
                POP     AX
                POPF
;---------------тут мы как бы закончили влезать не мешая...__________________
                RETN
TESTWIN         ENDP

b2m wrote:... как всегда, в инете пишут много, а реально работает из этого - шишь да маленько.
Тут мне, как обычно, хочется напомнить, что мешает плохим танцорам из страны Советов... :wink:
И порекомендовать читать не только много, но и вдумчиво. Тогда всё получится. 8)

Но с VxD я второй раз упражняться не хочу, ибо долго это.
А в данный момент мне как раз необходимы простенькие костылики...
iLavr
User avatar
Lavr
Supreme God
Posts: 16682
Joined: 21 Oct 2009 08:08
Location: Россия

Re: Windows 98/Me

Post by Lavr »

Lavr wrote:Приложение DOS может, как мне кажется, послать что-то Windows через Clipboard ...
Ну в общем-то эта идея с простым костыликом в черновом варианте сработала...
send.gif
Приложение Windows запускает приложение DOS, как было описано выше.
После чего с интервалом в 1 сек. начинает проверять Clipboard.

Приложение DOS - графическое, по нажатию на [Stop] левой кнопкой или
правой кнопкой в любом месте экрана, открывает Clipboard, очищает его,
заносит в Clipboard текст "ABCD", и закрывает Clipboard.
По сообщениям на экране видно, что все функции сработали корректно.
Как корректно приложению DOS работать с Clipboard под Windows подробно
изложили "классики марксизма" - братья Фроловы: :wink:
http://www.frolov-lib.ru/books/bsp/v06/ch7_3.htm

Приложение Windows проверяет пуст ли Clipboard. Если он не пуст, проверяется
тип данных, и если данные текстовые, Clipboard считывается. И только если
считан текст "ABCD", приложение Windows очищает Clipboard и посылает окну
приложения DOS события нажатия и отпускания [Alt] и [Enter].
Далее Clipboard снова циклически тестируется с интервалом в 1 сек.

Под Windows с Clipboard работают через Win API опять же в полном согласии
с "классиками марксизма": 8)
http://www.frolov-lib.ru/books/bsp/v17/ch2_1.htm

У них только нет, как быстро проверить пуст ли Clipboard, это лучше делать так:

Code: Select all

Declare Function CountClipboardFormats Lib "user32" () As Long
...
if CountClipboardFormats = 0 then MsgBox "Clipboard is empty !!!"
Думаю, пока мне этого костылика хватит, тем более, что он не был самоцелью...
You do not have the required permissions to view the files attached to this post.
iLavr
User avatar
Lavr
Supreme God
Posts: 16682
Joined: 21 Oct 2009 08:08
Location: Россия

Re: Windows 98/Me

Post by Lavr »

Lavr wrote:
Lavr wrote:Приложение DOS может, как мне кажется, послать что-то Windows через Clipboard ...
Ну в общем-то эта идея с простым костыликом в черновом варианте сработала...
Приложение Windows запускает приложение DOS, как было описано выше.
После чего с интервалом в 1 сек. начинает проверять Clipboard....
Сама идея оказалась очень правильная, только мне не понравился опрос по таймеру. :osad:
Это, и правда, довольно неуклюжий костыль... :osad:

Поэтому я сначала подумал, а не поставить ли hook на события мыши и отлавливать нажатие
в окне, к примеру, правой кнопки?
Но это сработало лишь для режима "сеанс MS DOS" в режиме окна. В полноэкранном режиме
этот трюк не проходит. События мыши не проникают через полноэкранный режим... :osad:

Вобще полноэкранный режим MS DOS - это какая-то вещь в себе, нигде толком не пишут, что
там конкретно работает и как. Максимум - что это "режим, аналогичный реальной DOS, но
эмулируемый средствами Window
s", причем настройку его определяет *.pif файл, вплоть до того,
что в каждом случае можно иметь собственный autoexec и config...
Если Windows чего-то не может сэмулировать, она предлагает выход в реальный DOS с
возвратом в неё. (Конечно, это всё справедливо для младших версий Windows, в старших -
ситуация еще сложнее... )

Ну и поскольку hook на события мыши не сработал, я подумал - а нельзя ли поставть
hook на события Clipboard? :roll:

Оказалось, что и никакой hook ставить не надо, механизм отслеживания Clipboard более
прост, хотя и мало известен: я лично - точно не знал... :cry:

Надо просто добавить свё окно к цепочке окон просмотра буфера обмена, и окна просмотра
буфера обмена получают сообщение WM_DRAWCLIPBOARD всякий раз, когда содержание
буфера изменяется. Этот механизм хорошо описан на русском по ссылкам:

http://vsokovikov.narod.ru/New_MSDN_API ... viewer.htm
http://vsokovikov.narod.ru/New_MSDN_API ... win_cb.htm
http://vsokovikov.narod.ru/New_MSDN_API ... bchain.htm
http://vsokovikov.narod.ru/New_MSDN_API ... win_cb.htm
http://vsokovikov.narod.ru/New_MSDN_API ... drawcb.htm
http://vsokovikov.narod.ru/New_MSDN_API ... viewer.htm

Попробую... жаль на hook событий мыши время зря потратил... :-?
iLavr
User avatar
Lavr
Supreme God
Posts: 16682
Joined: 21 Oct 2009 08:08
Location: Россия

Re: Windows 98/Me

Post by Lavr »

Lavr wrote:Надо просто добавить свё окно к цепочке окон просмотра буфера обмена, и окна просмотра
буфера обмена получают сообщение WM_DRAWCLIPBOARD всякий раз, когда содержание
буфера изменяется.
Великолепно этот механизм работает! :kruto:
clip.gif
На мой взгляд - это и есть самый простой и "безкостыльный" метод передавать из приложения DOS
в Windows практически что угодно! :roll:
Лишь бы со стороны Windows был свой "слушатель" в цепочке окон просмотра буфера обмена...
А своего "слушателя" я посадил в трей, чтобы он не маячил окном на экране (иконка там с
красным шаром).

Ну и поскольку я весьма посредственный программист на С++, мне очень помогли вот эти статьи:
С++ - GetClipboardData(CF_TEXT) - Stack Overflow
Пример Окна просмотра буфера обмена

Ну и последний момент преодолеть осталось: дело в том, что программа, ради которой я стараюсь,
принципиально написана без поддержки мыши. Видимо, придется написать под неё маленький резидент,
который запустит обслуживание мыши. 8)
You do not have the required permissions to view the files attached to this post.
iLavr