(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

WriteLn для C++Builder (исходники)

Источник: CppBuilder
Kent Reisdorph

Содержание

Введение

Программисты Delphi уже в течение долгого времени используют функцию WriteLn в качестве отладочного инструмента. Текст, переданный во WriteLn, направляется в консольное окно, превращая его в лог-файл реального времени. Используя подобный подход, вы можете отслеживать поведение своей программы в секциях кода, критичных с точки зрения времени, где обычные точки останова (breakpoints) не будут работать. К сожалению, C++Builder не включает в себя функцию WriteLn. Тем не менее, нет никаких причин для того, чтобы не реализовать ее самостоятельно. В этой статье я объясню вам, как это сделать. Как часть объяснения, мы рассмотрим также функции AllocConsole, GetStdHandle и WriteConsole Windows API.

WriteLn по-дельфийски

Использование функции WriteLn в Delphi состоит из двух шагов. Сначала вы выделяете консольное окно для вашего приложения, а затем уже вызываете WriteLn. Код выглядит примерно следующим образом:

AllocConsole();
WriteLn(`Entering Critical Section');
{ Тут что-то делаем }
WriteLn(`Exiting Critical Section');

AllocConsole - это функция Win32 API, и, как и подразумевает ее имя, она выделяет консольное окно для приложения. Каждое приложение может иметь свое собственное консольное окно - но только одно. Это справедливо как для GUI-приложений, так и для стандартных консольных приложений.

После того, как приложению выделено окно консоли, функция WriteLn выводит в него текст. Система простая, но чрезвычайно эффективная. Фактически, в некоторых ситуациях при отладке достаточно только ее.

Консольный вывод в C++

У C++Builder есть инструменты отладки, похожие на WriteLn. Диагностические макросы TRACE и WARN, а также функция OutputDebugString делают, в первом приближении, то же самое, что и функция WriteLn. Но их использование, тем не менее, страдает одним недостатком: их вывод направляется в log-файл, который не обновляется до тех пор, пока приложение не задержится на точке останова, или пока оно не завершится. Это ограничивает использование вышеупомянутых инструментов в некоторых ситуациях.

Но хорошие новости, кроме того, что WriteLn легко реализовать в C++Builder, состоят также в том, что вы можете включить в ее реализацию непосредственно функции управления консолью, что, в итоге, сделает использование вашей собственной функции WriteLn намного проще. WriteLn требует дескриптор выходного буфера для консольного окна, который вы можете получить посредством функции GetStdHandle. В целом это все будет выглядеть примерно так:

AllocConsole();
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
WriteConsole(handle, "Test", 4, 0, 0);

Давайте рассмотрим код внимательнее. Вызов AllocConsole, очевидно, выделяет консольное окно вашему приложению. Во второй строке функция GetStdHandle извлекает дескриптор стандартного выходного буфера. Вы передаете значение STD_OUTPUT_HANDLE в эту функцию, чтобы "попросить" Windows выдать вам дескриптор стандартного буфера.

Как только вы получили дескриптор стандартного выходного буфера, вы можете вызвать функцию WriteConsole для записи текста в консольное окно. Первый параметр функции WriteConsole представляет собой дескриптор стандартного буфера вывода, второй параметр - текст, который отправляется в консоль, третий параметр - количество выводимых символов.

WriteLn для C++Builder

Теперь, зная все необходимое, вы можете создать-таки вашу собственную функцию WriteLn. Для начала, давайте объявим ее прототип. Он очень прост:

void WriteLn(String text);

Как видите, функция принимает параметр типа String и ничего не возвращает. Разумеется, значение параметра text и будет тем самым выводимым в консоль текстом. Давайте теперь взглянем на WriteLn целиком:

void WriteLn(String text)
{
  static HANDLE handle;
  if(!handle) {
    AllocConsole();
    handle = GetStdHandle(STD_OUTPUT_HANDLE);
  }
  text += "\n";
  WriteConsole(handle, 
    text.c_str(), text.Length(), 0, 0);
}

Сначала вы объявляете статическую переменную handle - она подскажет вам, не было ли консольное окно уже выделено вашему приложению (вспомните, что статическая переменная имеет начальное значение, равное нулю, и сохраняет свое значение между вызовами функции). Если значение переменной handle равно нулю, то, значит, консольное окно еще не было выделено. Таким образом, вы можете вызвать функцию AllocConsole. Затем вы вызываете GetStdHandle для получения дескриптора стандартного выходного буфера. Далее, вы добавляете символ перевода новой строки в конец переданного в функцию текста. Это гарантирует, что каждая строка будет начинаться с новой строки. Наконец, вы вызываете WriteConsole для вывода текста в консольное окно. Обратите внимание, что вы передаете длину строки текста в качестве третьего параметра функции WriteConsole, чтобы строка полностью была выведена в консоль.

Пример

Листинг ниже является программой, использующей функцию WriteLn. Это главная форма с одной кнопкой. Когда вы нажимаете на кнопку, цикл вызывает функцию WriteLn для вывода двадцати строк текста в консольное окно.

//--------------------------------------------
#include 
#pragma hdrstop
 
#include "WriteLnU.h"
//--------------------------------------------
#pragma resource "*.dfm"
 
TForm1 *Form1;
 
// The WriteLn function.
void WriteLn(String text)
{
  static HANDLE handle;
  if (!handle) {
    AllocConsole();
    handle = GetStdHandle(STD_OUTPUT_HANDLE);
  }
  text += "\n";
  WriteConsole(handle,
    text.c_str(), text.Length(), 0, 0);
}
 
//--------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) 
  : TForm(Owner)
{
}
//--------------------------------------------
void __fastcall 
TForm1::Button1Click(TObject *Sender)
{
  for (int i=0;i<20;i++) {
    Application->ProcessMessages();
    WriteLn("Iteration: " + String(i));
    Sleep(100);
  }
}

Заключение

Функция WriteLn может быть замечательным инструментом отладки. Вы можете нечасто ее использовать, но, когда она нужна на самом деле, то ей нет замены.



 Распечатать »
 Правила публикации »
  Обсудить материал в конференции Embarcadero »
Написать редактору 
 Рекомендовать » Дата публикации: 11.10.2008 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
AutoCAD LT 2019 Commercial New Single-user ELD Annual Subscription
IBM DOMINO COLLABORATION EXPRESS AUTHORIZED USER LICENSE + SW SUBSCRIPTION & SUPPORT 12 MONTHS
Microsoft SQL CAL 2017 Sngl OLP 1License NoLevel UsrCAL
ESET NOD32 Антивирус - продление лицензии на 2 года на 3ПК
IBM RATIONAL Clearcase Floating User License + Sw Subscription & Support 12 Months
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
СУБД Oracle "с нуля"
Один день системного администратора
Delphi - проблемы и решения
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
Обсуждения в форумах
Пишу программы на заказ для студентов (187)
Пишу для студентов на с, с++, паскаль в средах ms visual studio, qt, builder, borland c, delphi....
 
Пишу программы на заказ профессионально (2282)
Пишу программы на заказ на языках Pascal (численные методы, списки, деревья, прерывания) под...
 
Ищу программиста для написания программы (21)
Ищу программиста ,владеющего Вижуал Бэйсик и программированием в Экселе, для написания...
 
Настройка меню "Пуск" Windows 7 при помощи реестра (3)
Скажите пожалуйста, а как можно закрепить ярлыки программ с помощью твиков реестра в левой части...
 
Ищу программиста PYTHON (1)
Ищу программиста для написание программ python 3 + библиотека tkinter Есть данные в БД...
 
 
 



    
rambler's top100 Rambler's Top100