На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела Visual Basic: Общие вопросы
Здесь обсуждаются вопросы по языку Visual Basic 1-6 (а так же по схожим языкам, как, например, PowerBASIC).
Вопросы по Visual Basic .NET (это который входит в состав Visual Studio 2002/2003/2005/2008+, для тех, кто не в курсе) обсуждаются в разделе .NET.

Обратите внимание:
1. Прежде чем начать новую тему или отправить сообщение, убедитесь, что Вы не нарушаете правил форума!
2. Обязательно воспользуйтесь поиском. Возможно, Ваш вопрос уже обсуждали. Полезные ссылки приведены ниже.
3. Темы с просьбой выполнить какую-либо работу за автора в этом разделе не обсуждаются. Студенты, вам сюда: ПОМОЩЬ СТУДЕНТАМ!
4. Используйте теги [ code=vba ] ...текст программы... [ /code ] для выделения текста программы подсветкой.
5. Помните, здесь телепатов нет. Формулируйте свой вопрос максимально грамотно и чётко: Как правильно задавать вопросы
6. Запрещено отвечать в темы месячной (и более) давности, без веских на то причин.

Полезные ссылки:
user posted image FAQ Сайта user posted image FAQ Раздела user posted image Кладовка user posted image Наши Исходники user posted image API-Guide user posted image Поиск по Разделу user posted image MSDN Library Online user posted image Google

Ваше мнение о модераторах: user posted image SCINER, user posted image B.V.
Модераторы: SCINER, B.V.
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> Создание консольных приложений на VB6 с помощью 10 строк кода :) , Новый кирпич от Хакера
    Товарищи по языку.

    Можно ли на VB6 создавать консольные приложения? Да так, чтобы консольные приложения можно было использовать с перенаправлениями ввода/вывода и конвейерами? Да так, чтобы всё это можно было делать очень быстро в RAD-манере? Добавив в проект всего-лишь крохотный модуль с 10 строчками кода?

    Я изыскал способ :yes:

    Кирпич EasyConsole + обсуждение трюка.

    Раскрывая секрет трюка, скажу, что используется две вещи:
    1) Найденные мною «секретные» опции VBP-файла.
    2) FileSystemObject (объектная модель позволяет работать со стандартными потоками, а не только с файлами).

    Консольное приложение пишется примерно в таком стиле:
    ExpandedWrap disabled
      Sub Main()
          EasyconInitialize
       
          stdout.WriteLine "What is your name?"
          Dim sName As String
          sName = stdin.ReadLine
          stdout.WriteLine "Hello, " + sName + "! Glad to see you here!"
      End Sub


    Нужно только добавить крохотный модуль в проект + сделать ещё пару пустяковых действий. В общем, смотрите оригинальные топики.
    Сообщение отредактировано: Хакер -

        Filka, ты не в теме. Или ты думаешь, что я один из тех глупых людей, для которых объектная модель FSO — спасительная простота, а WinAPI — ой как сложно чур меня. Если так, то ты ошибаешься.

        Во-первых, эти товарищи не проводили многих часов с отладчиком и дизассемблером, изучая внутренности vb6.exe, vba6.dll и msvbvm60.dll, как это делал я. Поэтому они не знаеют о секции [VBCompiler] и ключах C2Switches и LinkSwitches. Да судя по поиску — про них вообще никто кроме меня не писал. Поэтому эти товарищи пользуются богомерзкой утилитой Application Mode Changer чтобы сгенерировать EXE-файл с IMAGE_SUBSYSTEM_WINDOWS_CUI. Богомерзкой, во-первых, потому что есть editbin, а во вторых, потому что выходной exe-файл надо править после каждой перекомпиляции. У меня же он сразу после компиляции (после линковки) выходит с правильным флагом. Напоминаю, что в VB нет ничего близко похожего на опцию «Execute External Utility After Compilaton». Поэтому вызов Application Mode Changes / editbin остаётся выполнять только вручную. И к тому же у меня для получения изначально CUI-шных EXE-шников не надо иметь никаких сторонних утилит. Компиляция может быть произведена на абсолютно чистом сведеустановленном VB6.

        Во-вторых, у этих товарищей в распоряжение программиста отдаются только функции WriteFile/ReadFile, которые не предлагают такой удобной семантики работы с консолью, какая предлагается методами интерфейса ITextStream. Никакого тебе, ReadLine, к примеру. Это конечно не scanf(), но по крайней мере функциональный аналог gets(). Здесь же программисту придётся самостоятельно писать обёртку над ReadFile, которая бы реализовывала ReadLine-функционал. Хомячки не любят такую работу.

        В-третьих, в моём случае код, работающий с консолью получается полиморфный, потому что о работает с интерфейсом ITextStream. В случае чего, ссылкам stdin, stdout, stderr можно присвоить ссылку на абсолютно любой другой объект, реализующий этот COM-интерфейс, реализация которого может быть весьма экзотической, и это никак не отразится на коде, который работает с ITextStream. У них тоже можно заменить хендл, полученный от GetStdHandle, но только на другой хендл какого-либо ядерного объекта вроде пайпа, файла и т.п.

        Ну и в четвертых — они никак не осветили возникающую проблему: консольных приложения, полученные предложенным им способом, невозможно отлаживать. Я предложил два способа решения этой проблемы, они — ни одного. Хотя в их случае будет применим только первый из предложенных мною способов.
          Хакер, если у тебя кирпич опенсурсный (еще не смотрел), может, оформишь копию поста с VBStreets в этом разделе Наши Исходники ?
          Получишь DGM'ки от форума ;)
            Цитата B.V. @
            Хакер, если у тебя кирпич опенсурсный (еще не смотрел)

            OMG. Конечно опунсоурсный, не даром же речь о «10 строках кода».
            Копию поста со ссылкой на оригинальный стритсовский аттач?
              Цитата Хакер @
              Копию поста со ссылкой на оригинальный стритсовский аттач?

              Копию поста с прикрепленным к посту аттачем
              И со ссылочкой на оригинал, если угодно
                Так не пойдёт.
                  Скрытый текст

                  Цитата Хакер @
                  Так не пойдёт.
                  :blink: :scratch: :-?
                    Хакер, а где, кому и зачем могут понадобиться консольные ВБ6 приложения?
                      MIF, могут. Не так давно делал заказ, городил консоль через API.
                      Seriy-Coder, логика понятна - Хакер будет дорабатывать кирпич, исправлять баги (мало ли) - и перезаливать всего один аттач.
                      Сообщение отредактировано: Mikle -
                        Цитата Mikle @
                        Seriy-Coder, логика понятна - Хакер будет дорабатывать кирпич, исправлять баги (мало ли) - и перезаливать всего один аттач.

                        Боюсь, что логика немного иная :)
                          B.V., естественно ему выгодно пиаоить VBStreets, не вижу в этом ничего предосудительного, раз есть, чем пиарить.
                            Цитата MIF @
                            Хакер, а где, кому и зачем могут понадобиться консольные ВБ6 приложения?

                            Вопрос глупый, потому что в нём фигурирует глупая формулировка «консольные VB6-приложения».

                            Никому не нужны консольные VB6-приложения.

                            Многим нужны просто консольные приложения. В каждом случае встаёт вопрос: на чём писать это консольное приложение. У тех, кто знает много языков, в числе которых VB, теперь появляется ещё один вариант. А есть ещё пласт товарищей, которые по прежнему кроме VB ничего не знают — для них это вообще единственный спасительный вариант простого и предельно быстрого способа написания консольного приложения.

                            Помимо всего прочего, классический VB сложно обогнать по критерию «RAD-средство что-бы взять и что-то черновое набросать». Месяц назад я работал над одним средним проектом, код которого компилировался под FreeBSD компилятором gcc.

                            Так вот, несмотря на то, что я несколько лет проработал в VC2005, и пробовал на вкус VC2008 — я всё равно вернулся к VC6.0 и для С/С++-проектов пользуюсь именно этой средой. Так вот в рамках работы над тем проектом было крайней неудобно запускать сборку продекта под Unix-средой, дожидаться результата (содержащего error-ы и warning-и), а потом сто раз переключаться между Win-машиной и nix-машиной чтобы «сопоставлять» ошибки из вывода gcc с кодом.

                            Поэтому я решил прикрутить gcc к MS VC++ 6.0. Это совершенно лёгкое мероприятие: мой makefile был кроссплатформенным, оставалось только поставить cygwin (в котором был виндовый gcc, h- и lib-файлы для POSIX-функций).

                            Однако вот беда: MSVC 6.0 IDE не могла извлекать номер строк из вывода, который давал GCC.

                            У CL был такой вывод:
                            ExpandedWrap disabled
                              src/vinftree.c(716):2: #error foo
                              G:\dev\foo\bar.cpp(141) : error C2146: syntax error : missing ';' before identifier 'qw'
                              G:\dev\foo\bar.cpp(141) : error C2501: 'qwe' : missing storage-class or type specifiers
                              G:\dev\foo\bar.cpp(141) : fatal error C1004: unexpected end of file found

                            А у GCC такой:
                            ExpandedWrap disabled
                              src/vinftree.c:716:2: #error foo
                              src/vinftree.c:717:2: #error baz
                              src/vinftree.c:718: error: parse error before "wei8qr"


                            То есть в BuildLog ты просто не можешь даблкликнуть на строчку с error-ом/warning-ом, чтобы IDE сама перенесла тебя на соответствующий файл на соответствующую строчку. Когда строчек в каждом исходнике под пару-тройку тысяч — это дико неудобно.

                            Это не просто неудобно, это дико увеличивает время, необходимое на устранение ошибок. Это нужно решить, решить срочно, иначе проект затянется.

                            Как это решить? Как это решить с учётом того, что gcc не имеет опции для изменения формата вывода? Без модификации исходников gcc и пересборки gcc в рамказ cygwin-а? Без модификации бинарника gcc (потому что в его кишкаш строчки вроде «%s:%u», которую можно было бы изменить на «%s:(%u)» всё равно не было.

                            Как это решить за 10 минут, в общем?

                            Я придумал простое решение: нужно написать консольную утилиту, которая бы работала в рамках конвейера, принимая на вход gcc-шный вывод, и выдавая исправленный строки (надо просто заворачивать номера строк в скобки).

                            Я написал эту консольную крохотную утилитку — linenumfix и модифицировал свой makefile так, что под Windows при наличии linenumfix-а в составе toolchain-а он автоматически бы применялся.

                            То есть если мой проект попадает на машину под linenumfix-а, то GCC вызывается так:
                            ExpandedWrap disabled
                              gcc lalalalalala


                            А если linenumfix есть, то так:
                            ExpandedWrap disabled
                              gcc lalalalalala 2<&1 | linenumfix


                            И в билд-лог попадает исправленный вывод GCC, в котором сообщения об ошибках кликабельны и иммитируют Ctrl+G на нужную строку.
                            user posted image
                            Красота.



                            Вопрос только в том, как быстрее всего (в условиях дичайшей спешки) написать linenumfix? Быстрее всего я бы написал его на PHP: обошёлся бы одним вызовом preg_replace. Но включать в toolchain скрипт на PHP, то есть делать так, что компиляция проекта становится невозможной без PHP — недопустимо.

                            Поэтому я написал linenumfix на Си и уложился в 100 строчек. А если бы к тому моменту мой кирпич был бы у меня в распоряжении, я бы написал linenumfix на VB6 и уложился бы в 10 строчек.

                            Скрытый текст
                            (Конечно тру-последователи Unix-идеологии скажут, что вообще не надо было писать свой linenumfix, а надо было заюзать awk.)


                            В общем, есть ещё тьма случаев, когда нужно написать консольное приложение, и на VB6 его написать в несколько раз быстрее, чем на С/С++. Особенно, к примеру, если стоит задача поработать с COM-объектами.

                            Вот например задачка: в качестве параметра командной строки утилита принимает дисплэй-нэйм OBJREF-моникера. По нему она получает объект, опрашивает его и выводит в stdout результаты, полученные в ходе опроса. Готов поспорить, что на VB6 это будет сделать в разы быстрее и проще, чем на С++ и уж тем более С без плюсов.
                              Цитата Mikle @
                              не вижу в этом ничего предосудительного

                              Так никто и не судит :)

                              Цитата Хакер @
                              Поэтому я написал linenumfix на Си и уложился в 100 строчек.

                              Зачем, если есть std::regex? Или мы не ищем легких путей?
                                Цитата B.V. @
                                Цитата
                                Поэтому я написал linenumfix на Си и уложился в 100 строчек.


                                Зачем, если есть std::regex? Или мы не ищем легких путей?

                                Или мы не знаем разницу между Си и Си++? К тому же это из нового стандарта, с помощью VC6 это не скомпилировать.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0455 ]   [ 16 queries used ]   [ Generated: 7.05.24, 21:25 GMT ]