Задача:
При наведении мыши на определенный контрол, выводить подсказку о его назначении в строке состояния (StatusBar).
Решение:
С первого взгляда на проблему хочется тут же взяться и начать писать обработчики событий OnMouseEnter и OnMouseLeave вроде этих:
void __fastcall TForm::SomeControlMouseEnter(TObject *Sender)
{
// Выводим сообщение в строку состояния
StatusBar1->SimpleText = "Вы навели мышь на вот этот контрол";
}
//---------------------------------------------------------------------------
void __fastcall TAddNewLocationForm::BInsertMouseLeave(TObject *Sender)
{
// Очищаем строку состояния
StatusBar1->SimpleText = "";
}
Конечно, это вполне работоспособный код, но если обработать таким образом нужно много элементов на форме, сразу задумываешься: а нет ли способа покороче да поуниверсальнее.
Мы может воспользоваться компонентом ApplicationEvents (группа Additional в BDS 2006), отвечающим за обработку событий приложения. Нам пригодится событие OnHint.
Оно возникает, когда курсор мыши перемещается над компонентом или элементом меню. При этом значение свойства Hint текущего компонента заносится в одноименное свойство приложения: Application->Hint.
Cначала задайте текст подсказок в свойстве Hint требуемых контролов. Дальше пишем простой обработчик события OnHint:
void __fastcall TForm::ApplicationEvents1Hint(TObject *Sender)
{
StatusBar1->SimpleText = Application->Hint;
}
Собственно, всё. Теперь при наведении мыши на компоненты, в статусной строке будут возникать подсказки, соответствующие данному компоненту.
Задача решена.
Если вы когда-нибудь пользовались компонентом TRadioGroup, то, пожалуй, знаете, насколько он удобен при динамическом формировании списка переключателей. Всего-то и нужно, что добавлять и удалять строки списка типа TStringList
RadioGroup1->Items->Clear(); // удаление всех элементов
RadioGroup1->Items->Add("Первая точка"); // добавление новых
RadioGroup1->Items->Add("Вторая точка");
Ну и конечно же, вы знаете, что определить выбранную точку можно по значению свойства ItemIndex. Нумерация начинается с нуля, как заведено.
А вот вопрос: как получить доступ к свойствам отдельных элементов, сперва вызывает проблемы. На самом деле всё просто, нужно использовать массив Controls. Вот доступ к выделенному элементу:
int idx = RadioGroup1->ItemIndex; // запоминаем индекс
RadioGroup1->Controls[idx]->Enabled = false; // делаем недоступным
RadioGroup1->Controls[idx]->Visible = false; // скрываем
Ну и так далее.
Для обхода всех элементов, воспользуемся циклом, взяв количество элементов из свойства ControlCount:
for (int i = 0; i < RadioGroup1->ControlCount; i++)
RadioGroup1->Controls[i]->Caption = IntToStr(i) + "-й элемент";
В результате все элементы списка будут переименованы.
Так же не забывайте про методы BeginUpdate() и EndUpdate(), которые позволят избежать мерцания списка при изменении состава элементов.
RadioGroup1->Items->BeginUpdate(); // отключаем обновление элементов
for (int i = 0; i < RadioGroup1->ControlCount; i++)
RadioGroup1->Controls[i]->Caption += "(" + IntToStr(i) + ")";
RadioGroup1->Items->EndUpdate(); // включаем обратно
Сканировать определенную папку и получить имена всех или определенных файлов вам позволит следующий код:
int ires;
TSearchRec SR;
AnsiString ext; // Расширение.
// Очищаем список файлов в компоненте ListBox
List->Clear();
// Задаем параметры поиска: где искать и что.
ires = FindFirst("C:\\*.*", faAnyFile | faArchive, SR);
while (ires == 0)
{
// Если нужны только определенные типы файлов,
// то ведем проверку по расширению.
ext = ExtractFileExt(SR.Name);
if ((ext == ".bmp") || (ext == ".jpg")) {
// Заносим имена файлов в список.
List->Items->Add(SR.Name);
}
// Переход к следующему файлу к каталоге.
ires = FindNext(SR);
}
// Поиск завершен.
FindClose(SR);
Основан на функциях Find.
int FindFirst (AnsiString Path, int Attr, TSearchRec & F);
Находит первый файл с заданными атрибутами в указанном каталоге.
Атрибуты передаются с помощью следующих констант: faReadOnly, faHidden, faSysFile, faVolumeID, faDirectory, faArchive.
В последний аргумент функции заносится результат поиска.
Давольно давно искал место, куда бы сваливать всякие полезные куски кода. Ведь как бывает: сталкиваешься с новой областью в программировании, начинаешь изучать. Находишь решение. И хочется, чтобы это решение не потерялось, чтобы его можно было быстро взять, если понадобиться в следующем проекте.
Сначала хотел создать отдельный сайт, но поленился, и сделал эту рубрику.
Встречайте. Code Chips — «Кусочки кода».
Первая запись про то, как преобразовать картинку jpeg в формат bmp в C++ Builder.
Функция конвертирует файл формата jpeg в bmp.
На входе полное имя файла, возвращает true в случае успешной конвертации.
bool JPEG2BMP(AnsiString FileName)
{
TJPEGImage *jpg = new TJPEGImage;
Graphics::TBitmap *bmp = new Graphics::TBitmap;
bool ok = true; // Маркер хорошего поведения.
try {
jpg->CompressionQuality = 100; // Качество сжатия.
jpg->LoadFromFile(FileName); // Загружаем jpeg.
try {
bmp->Assign(jpg); // Переносим данные в bmp.
bmp->SaveToFile(ChangeFileExt(FileName, ".bmp"));
} catch (...) {
ok = false;
}
} catch (...) {
ok = false;
}
jpg->Free();
bmp->Free();
return ok;
}
Для информирования пользователя об ошибке можно добавить перед return что-то из ряда:
if (!ok)
ShowMessage("Конвертирование не увенчалось успехом");