Главная » C++, C++ Builder » Библиотека стандартных шаблонов (STL) в CBuilder (FAQ)

0

Почему при использовании класса vector выдается целый ворох ошибок?

Наверное, вы делаете что-нибудь типа:

#include <vector.h> int func(void)

{

vector<int> array;

}

и на строке vector<int> как раз и получаете свой ворох ошибок. Для исправления ситуации используйте именованную область видимости для STL, которая называется std. Вот код, который разрешит ваши проблемы:

#include <vector.h>

use namespace std; // Просто добавьте эту строку

int func(void)

{

vector<int> array;

}

Можно ли использовать STL в компонентах?

Естественно. Не забудьте только добавить соответствующий заголовочный файл (vector, list и т. п.) и полностью определить имя компонента STL, используя выражение std::. Что касается всего остального, можно смело сказать, что компоненты STL работают в компонентах точно также, как и в простых приложениях.

Библиотека визуальных компонентов (VCL)

Как программно добавить элементы в список или комбинированный список?

Это можно сделать при помощи метода Add свойство Items. Другими словами, когда вы работаете с элементами списка или комбинированного списка, вы работаете напрямую со свойством Items. CBuilder разделил всю работу со списками (комбинированными списками) на отдельные части — для обработки данных и модификации самих списков.

Например для того, чтобы добавить элемент в конец списка, вам наде написать следующую строку кода:

ListBox1->Items->Add( "MyItem1" );

Для модификации заданного элемента списка вы обращаетесь к свойству items как к массиву и пишите следующее:

ListBox1->Items[nInd] = "MyItem2";

И, наконец, для удаления элемента из списка, используя метод Remove: ListBox1->Remove(0); // Удаление первого элемента списка

Как в своем компоненте или форме обработать сообщение Windows (WM_USER)?

Любое сообщение Windows из числа тех, что не обрабатываются  компонентом CBuilder, может быть добавлено в него при помощи карты сообщения (message map). Для этого определите сообщение как константу:

#define WM_MY_Message (WM_USER+1)

После этого в описание класса формы или компонента (находящееся, как известно, в заголовочном файле) добавьте следующие строки:

BEGIN_MESSAGE_MAP

MESSAGE_HANDLER(WM_MY_MESSAGE,TMessage,   OnMyMessage) END_MESSAGE_MAP

Наконец, определите в своем классе метод OnMyMessage как метод класса, имеющий один аргумент типа TMessage:

void __fastcall OnMyMessage( TMessage& msg );

Далее, уже в коде функции вы можете определить любые действия, которые должны выполняться при получении заданного пользователем сообщения. Если  вы  используете  сообщение, определенное Windows, но не имеющее воплощения в CBuilder, опустите последний шаг. Все остальные шаги останутся точно такими же.

Когда следует использовать модификатор __fastcall?

Не обязательно использовать модификатор fastcall в ваших  собственных  методах.  Только методы, добавляемые в компоненты, должны использовать его в обязательном порядке. Методы, замещающие  в ваших компонентах методы VCL так же должны применять __fastcall.

Все это вызвано тем, что VCL была написана на языке Pascal. В языках C++ и Pascal используются разные соглашения о вызовах, в связи с чем и был введен модификатор __fastcall — для корректного истолкования аргументов.

Почему при инсталляции собственных компонентов появляются сообщения о странных ошибках?

Мне кажется, вопрос должен звучать так: «При инсталляции все вроде бы работает нормально, но компонент ведет себя странно — выдает сообщение о нарушении прав доступа (access violation). Как с этим бороться?»

Скорее всего, при компиляции компонента не  производилось  выравнивание  по  границе  слова. Если вы изменили выравнивание директивой компилятора С++ или Pascal, компонент может выдавать непредсказуемые результаты.

Как добавить горизонтальную полосу прокрутки в окно списка (ListBox)?

Это весьма распространенная при программировании под Windows проблема. Добавить горизонтальную полосу прокрутки в окно списка несложно, но работать нормально она не будет. Дело в  том, что вы должны установить горизонтальный размер списка для того, чтобы знать, насколько далеко его надо прокручивать. Для этого выберите самую длинную строку в списке и установите размер горизонтальной прокрутки так, чтобы он был равен длине этой строки. Сделать это надо следующим образом:

ListBox1->SendMessage(LB_SETHORIZONTALEXTENT,  m_nMaxLength,  0);

где  m_nMaxLength  —  целое  значение,  представляющее  собой  длину  максимальной  строки  в пикселях. Для определения длины строки можно использовать метод GetTextExtent:

SIZE sz;

GetTextExtentPoint32(ListBox1->Handle,szStrng, strlen(szString), &sz);

m_nMaxLength = sz.cx;

Можно ли использовать MessageDlg из Delphi в CBuilder?

Да, функцию MessageDlg можно использовать в CBuilder. У нее, правда, довольно замысловатый синтаксис:

MessageDlg("Status Message", mtError, TMsgDlgButtons() << mbYes << mbNo, 0)

Как инсталлировать компонент Delphi в CBuilder?

Для того, чтобы сынсталлировать компонент Delphi в CBuilder вам надо располагать исходным кодом этого компонента, так как сынсталлировать DCU (Delphi Component Unit) в CBuilder нельзя. Для инсталляции исходного кода вам надо проделать обычную процедуру  инсталляции компонента в CBuilder, выбрав в качестве исходного файла файл PAS. Весь остальной процесс останется неизменным. CBuilder одинаково легко компилирует исходный код, написанный как на C++, так и на Pascal.

Замечание

Не все компоненты Delphi будут работать в CBuilder. Как правило, проблем не возникнет, но если компонент Pascal использует свойство типа Real, не поддерживаемого CBuilder, при попытке использования компонента в своих приложениях вы получите странную ошибку компиляции (Real not supported, то есть тип Real не поддерживается).

Почему нельзя определить в программе элемент моего собственного компонента?

Как я понимаю, вам хотелось бы использовать конструкции типа: TEdit myEdit;

myEdit.somfunc();

К сожалению, использовать подобные вещи нельзя. Вместо этого вам надо в динамической памяти создать экземпляр класса TEdit при помощи оператора new. Это делается из-за того, что объекты VCL написаны на Pascal и уничтожаются  по-своему. Для создания экземпляра объекта VCL в вашем приложении следует написать следующее:

TEdit *pEdit = new TEdit(this); pEdit->Parent = this;

Как разбить полное имя файла на составляющие элементы?

Функция ExtractFileExt извлекает расширение из имени файла и возвращает его в качестве строки: string Ext = ExtractFileExt(FileName);

Как получить доступ к отдельным кускам растрового рисунка?

Используйте свойство Pixels растрового рисунка.

Как изменить элемент в списке, кроме как удалить и добавить снова?

Элементы списка хранятся в свойстве String массива  Items. Вы можете напрямую изменять эти строки через это свойство-массив. Например, чтобы получить первую строку в списке (с индексом

0) и добавить в нее букву W, вам надо сделать следующее:

string s = List1->Items->Strings[0]; s += "W";

List1->Items->Strings[0] = s;

Как изменить цвет текста на кнопке?

Вы можете изменить цвет текста (но не цвет фона) кнопки, использовав для этого свойство Font-

>Color. Например, чтобы сделать текст текста красным, вам надо написать следующее: Button1->Font->Color = clRed;

Как хранить информацию, связанную с элементом списка?

Используйте свойство Items; вы можете работать с элементом списка, устанавливая или получая свойство Items->Object для него.

Как создавать растровые рисунки на кнопках во время исполнения?

Это просто. Как и все растровые рисунки, рисунки на кнопках (TBitBtn) создаются как растровый рисунок размером 1 на 1 пиксель. Для того, чтобы увелич ить их до желаемого размера, установите значения свойств Width и Height в соответствующие значения. После этого можно использовать свойство Canvas кнопки для того, чтобы что-то отобразить на ней. При этом надо помнить,   что   цвет   пикселя   в   левом   нижнем   углу   растрового   рисунка   используется   как «прозрачный» цвет кнопки.

Сказанное выше имеет силу только для случая создания объекта TBitBtn во время исполнения.

Если же  вы собираетесь разрисовать уже существующую кнопку этого типа, задание  значений свойств Width и Height можно опустить.

Дочернее окно MDI не закрывается. Как можно его закрыть?

Вам надо добавить следующую строку в код метода FormClose дочерней формы MDI: Action = caFree;

По умолчанию дочерние окна не закрываются, а минимизируются. Зачем — я не знаю.

Как в CBuilder поместить дату и время в строку состояния?

Добавление в строку состояния текущих даты и времени — дело не хитрое. Вы можете получить текущие дату и время при посредстве функции VCL Now(), которая возвращает их как объект TDateTime.

Для того, чтобы поместить полученные данные в панель состояния, вам надо создать в ней секции (panel). После этого при помощи свойства Items секций вы устанавливаете текст, отображаемый в них. Для этого следует написать что-то вроде:

StatusBar->Panels->Items[nTimeIndex]->Text =  strTime; StatusBar->Panels->Items[nDateIndex]->Text = strDate;

В этом примере nTimeIndex это индекс секции, в которой вы хотите отображать время, а nDateIndex — секции даты; StrTime и strDate это строки времени и даты соответственно. Если вам не нравится использовать объект TDateTime, просто подключите файл <time.h> и используйте функцию localtime для получения даты и времени в местном формате.

Как изменить цвет фона формы?

На первый взгляд, нет ничего проще — можно установить свойство формы Color в  значение любого цвета. К большому сожалению, это не работает (по крайней мере в версии 1.0). С другой стороны, справиться с этой ошибкой не намного сложнее. Надо просто добавить изменение цвета формы в обработчик события формы  OnCreate:

Color = clRed; // Цвет фона установлен

Как преобразовать введенное в поле редактирования значение в число с плавающей точкой?

Для того, чтобы преобразовать информацию введенную в поле редактирования в число с плавающей точкой вам надо преобразовать свойство Text этого поля, как это показано в следующем коде:

double dValue = atof(Edit1->Text.c_str());

Данный фрагмент  кода извлекает введенное в поле редактирования значение в буфер char * и передает его в функцию atof, которая собственно и проводит преобразование из char * в double. Для определения функции atof вам, возможно, придется подключить файл <math.h>. <$FХочется добавить — возьмите за правило проводить подобные преобразования внутри блока try … except

— это обезопасит вашу программу от ошибок пользователя — Примеч. перев.>

Как загрузить растровый рисунок во время исполнения?

Это несколько зависит от того откуда, собственно, вы собираетесь его загружать. Для того, чтобы загрузить растровый рисунок из файла во время исполнения, следует использовать метод LoadFromFile. Например, для загрузки рисунка из файла в растровый рисунок Bitmap1,  вам следует написать:

Bitmap1->LoadFromFile("c:\\windows\\somebitmap.bmp");

Замечание

Для того, чтобы получить обратную косую черту (backslash), в C/C++ вам нужно поставить две такие черты подряд.

Как запретить один из переключателей в группе?

Для   того,    чтобы    обратиться    к    элементу    группы    переключателей    (radio    buttons), обычно используется свойство Items (RadioGroup->Items). Для запрещения и разрешения элементов группы вам хотелось бы работать с самими управляющими элементами, а не с их заголовками. Так что неудивительно, что для обращения к элементам как к объектам нужно использовать свойство Controls объекта RadioGroup (группа переключателей). Вот кусочек кода, который запретит выбор третьего (нумерация идет с нуля) переключателя из группы:

RadioGroup1->Controls[2]->Enabled = false;

Источник: Теллес М. – Borland C++ Builder. Библиотека программиста – 1998

По теме:

  • Комментарии