Как создать две консоли в одном процессе? Я так понимаю нужно делать два процесса? Задача такова: В одной консоли ловятся события мыши, а в другом они отображаются?
XshStasX, Нужна именно вторая консоль? Один процесс так не может. А ListBox или многострочный Edit для отображения событий не подойдёт?
А есть функции для работы с "чужой" консолью, но при этом чтоб и "своей" пользоваться можно было? Или нужны пайпы ??
XshStasX, Ещё раз: одновременно консоль у процесса может быть только одна. Прицепиться к чужой консоли можно, но для этого надо освободить текущую (FreeConsole() / AttachConsole()). Связь между процессами можно реализовать по разному, в том числе и пайпом. Можно вообще без коммуникаций, наверное: назапускать нужное количество консольных заглушек, которые просто ждут ивента и выходят, а в основной программе хватать попеременно их консоли и рулить.
csrss не поддерживает создание более одной консоли на процесс. Кстати говоря, консоль AllocConsole() "не совсем такая", как "родная", которую он получает при старте процесса с SubSystem == IMAGE_SUBSYSTEM_WINDOWS_CUI. Тебе не нужна консоль, тебе пойдут обычные окна. Нарисуешь красиво, похоже на консоль - все поверят
В общем может кому то пригодится, код. Программа состоит из двух частей, первая(сервер) шлет второй(клиенту) программе данные, и клиент их обрабатывает и отображает. Сервер запускает клиента. Сервер шлет программе клиенту, данные о состоянии кнопок мыши. Клиент: Код (Text): .386 .model flat,stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc include \masm32\include\masm32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\masm32.lib TPOINT STRUCT X WORD ? Y WORD ? TPOINT ENDS MOUSE_EVENT_RECORD_ STRUCT X WORD ? Y WORD ? dwButtonState DWORD ? dwControlKeyState DWORD ? dwEventFlags DWORD ? MOUSE_EVENT_RECORD_ ENDS .const pipe_name db "\\.\pipe\console_pipe",0 event_exit db "event_exit",0 ;_______________ X db "X:",0 Y db "Y:",0 Left1 db "levaya knopka",0 Left2 db "srednay knopka",0; Left3 db "FROM_LEFT_3RD_BUTTON_PRESSED",0 Left4 db "FROM_LEFT_4TH_BUTTON_PRESSED",0 Left5 db "pravaya knopka ",0 ClickDouble db "2 click",0; MouseHEELED db "MOUSE_HWHEELED",0; MouseMoved db "move mouse",0; MouseWHEELED db "koleso prokrucheno",0; ;_______________ .data? Point TPOINT <0>; Mouse MOUSE_EVENT_RECORD_ <0> hPipe HANDLE <0>; t dword 0; .data .code print_str proc push ebp mov ebp,esp add esp,-4 ; ebp -4 ; temp ; ebp + 12 buf ;ebp +8 hout push edi push ecx mov ecx,255 mov eax,0 lea edi,[ebp+12] mov edi,[edi] repnz scasb sub edi,[ebp+12] lea eax,[ebp-4] push eax push Point push edi push [ebp+12] push [ebp+8] call WriteConsoleOutputCharacter mov eax,[ebp-4] inc Point.Y pop ecx pop edi add esp,4 pop ebp ret 8 print_str endp mouse_proc proc push ebp mov ebp,esp mov [Point.Y],0 mov eax,[Mouse.dwButtonState] and eax,FROM_LEFT_1ST_BUTTON_PRESSED jz @L1 push offset Left1 push [ebp+8] call print_str @L1: mov eax,[Mouse.dwButtonState] and eax,RIGHTMOST_BUTTON_PRESSED jz @L2 push offset Left5 push [ebp+8] call print_str @L2: mov eax,[Mouse.dwButtonState] and eax,FROM_LEFT_2ND_BUTTON_PRESSED jz @L3 push offset Left2 push [ebp+8] call print_str @L3: mov eax,[Mouse.dwButtonState] and eax,FROM_LEFT_3RD_BUTTON_PRESSED jz @L4 push offset Left3 push [ebp+8] call print_str @L4: mov eax,[Mouse.dwButtonState] and eax,FROM_LEFT_4TH_BUTTON_PRESSED jz @L5 push offset Left4 push [ebp+8] call print_str @L5: mov eax,[Mouse.dwEventFlags] and eax,8 jz @L6 push offset MouseHEELED push [ebp+8] call print_str @L6: mov eax,[Mouse.dwEventFlags ] and eax,DOUBLE_CLICK jz @L7 push offset ClickDouble push [ebp+8] call print_str @L7: mov eax,[Mouse.dwEventFlags ] and eax,MOUSE_MOVED jz @L8 push offset MouseMoved push [ebp+8] call print_str @L8: mov eax,[Mouse.dwEventFlags ] and eax,4 jz @L9 push offset MouseWHEELED push [ebp+8] call print_str @L9: pop ebp ret 4 mouse_proc endp start: mov ebp,esp add esp,-8 call AllocConsole push STD_OUTPUT_HANDLE call GetStdHandle mov [ebp-4],eax push 1000 call Sleep push 0 push FILE_ATTRIBUTE_NORMAL push OPEN_EXISTING push 0 push 0 push GENERIC_READ push offset pipe_name call CreateFile cmp eax,INVALID_HANDLE_VALUE je @exit1 mov [hPipe],eax @main: push 0 push offset t push sizeof MOUSE_EVENT_RECORD push offset Mouse push [hPipe] call ReadFile cmp eax,0 je @exit lea eax,[ebp-8] push eax push 0 push 1000 push 32 push [ebp-4] call FillConsoleOutputCharacter push [ebp-4] call mouse_proc jmp @main @exit: push [hPipe] call CloseHandle @exit1: add esp,8 push 0 call ExitProcess end start Сервер:
Буду рад если кто-то укажет как этот код можно было сделать,лучше. П.С не заботился о очистке ресурсов.
Пожалуй, кое что можно предложить. Есть ли какой-то тайный смысл в том, чтобы линковать программу как GUI и в самом начале делать AllocConsole()? Для консольной программы по понятным причинам вызов обломится. WriteConsoleOutputCharacter() использует стандартную структуру COORD (есть в Windows.Inc из MASM32), незачем изобретать некий TPOINT. MOUSE_EVENT_RECORD там тоже есть. Необходимо учесть, однако, что при передаче структуры в функцию «по значению» она копируется в стэк целиком. Объявления переменных типа hPipe HANDLE <0> в секции неинициализированных данных не дают подразумеваемого эффекта (в смысле неинициализированности). .data и следом .code, хоть и не влияют на качество, немного сбивают с толку. Ручная адресация от ebp без объявления хотя бы equ-символов сбивают с толку ещё хуже: ладно бы следить за esp в функции с FPO, но тут-то можно воспользоваться возможностями ассемблера для улучшения читаемости? Можно считать что это — мелочи.
Что такое equ символы ? масм ругался на подобное : Mouse MOUSE_EVENT_RECORD <0> вот такой ошибкой: initialize must be a string or single item Как устранить ошибку, не понял сделал так как получилось)). Да, но указатель и структура равны 4 байта . Хотя на x64 лучше передать указатель, да?