private: // User declarations
void __fastcall LeftFunction(TObject *Sender);
public: // User declarations
__fastcall TForm1(TComponent* Owner);
VCL
Здесь размещаются вопросы связанные с использованием и разработкой компонентов VCL.
Как программно присвоить кнопке обработчик события OnClick?
Ответ:
Вот объявление:
Пример:
Код:
Вот определение:
Пример:
Код:
void __fastcall TForm1::LeftFunction(TObject *Sender){
ShowMessage("Test");
}
ShowMessage("Test");
}
Здесь присвоение:
Пример:
Код:
TForm1->BitBtn2->OnClick = TForm1::LeftFunction;
Автор ответа: kot_
Как выравнять текст в ячейках, столбцах, строках StringGrid?
Пример:
Код:
void __fastcall TForm1::StringGrid1DrawCell(TObject *Sender, int ACol,
int ARow, TRect &Rect, TGridDrawState State)
{
UINT uFormat = DT_LEFT | DT_VCENTER /*| DT_WORDBREAK*/ ; //по умолчанию влево
switch (ACol)
{
case 1:
uFormat = DT_CENTER | DT_VCENTER ;//по центру
break;
case 2:
case 4:
uFormat = DT_RIGHT | DT_VCENTER ;//вправо
break;
}
StringGrid1->Canvas->FillRect(Rect);
DrawText(StringGrid1->Canvas->Handle, // handle to device context
StringGrid1->Cells[ACol][ARow].c_str(), // pointer to string to draw
StringGrid1->Cells[ACol][ARow].Length(), // string length, in characters
&Rect, // pointer to structure with formatting dimensions
uFormat // text-drawing flags
);
}
int ARow, TRect &Rect, TGridDrawState State)
{
UINT uFormat = DT_LEFT | DT_VCENTER /*| DT_WORDBREAK*/ ; //по умолчанию влево
switch (ACol)
{
case 1:
uFormat = DT_CENTER | DT_VCENTER ;//по центру
break;
case 2:
case 4:
uFormat = DT_RIGHT | DT_VCENTER ;//вправо
break;
}
StringGrid1->Canvas->FillRect(Rect);
DrawText(StringGrid1->Canvas->Handle, // handle to device context
StringGrid1->Cells[ACol][ARow].c_str(), // pointer to string to draw
StringGrid1->Cells[ACol][ARow].Length(), // string length, in characters
&Rect, // pointer to structure with formatting dimensions
uFormat // text-drawing flags
);
}
Автор ответа: ***
Как сделать втопленную кнопку без дополнительных компонентов как
через Windows API (свойство WS_BORDER)?
Ответ:
Данный код делает все кнопки класса TButton на текущей форме втопленными.
Пример:
Код:
DoubleBuffered = true;
for (int i=0; i < ControlCount;i++) {
if (AnsiString(Controls->ClassName())=="TButton"){
Controls->ControlStyle << csFramed;
}
}
Repaint();
for (int i=0; i < ControlCount;i++) {
if (AnsiString(Controls->ClassName())=="TButton"){
Controls->ControlStyle << csFramed;
}
}
Repaint();
Автор ответа: SABROG
Как обрабатывать сообщения окна (WM_*)?
1. Ответ:
Это можно сделать так:
Пример:
Код:
// hpp
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *Button1;
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
protected: virtual void __fastcall WndProc(Messages::TMessage&); // переопределяем стандартный метод WndProc на свой - виртуальный
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
// cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::WndProc(TMessage&msg)
{
switch (msg.Msg)
{
case WM_CLOSE: // реакция на закрытие формы
MessageBox(0,"Exit program",0,MB_OK);
}
TForm::WndProc(msg); // вызываем стандартный метод
}
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *Button1;
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
protected: virtual void __fastcall WndProc(Messages::TMessage&); // переопределяем стандартный метод WndProc на свой - виртуальный
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
// cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::WndProc(TMessage&msg)
{
switch (msg.Msg)
{
case WM_CLOSE: // реакция на закрытие формы
MessageBox(0,"Exit program",0,MB_OK);
}
TForm::WndProc(msg); // вызываем стандартный метод
}
2. Ответ:
Еще один вариант (при таком методе, ловятся не все сообщения):
Пример:
Код:
// hpp
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *Button1;
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
void __fastcall AppMessage(tagMSG &Msg, bool &Handled); // определяем функцию, которая будет ловить сообщения
};
// cpp
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
Application->OnMessage = AppMessage; // переопределяем функцию, которая будет ловить сообщения
}
const WM_FILEREADY = WM_USER + 2000;
void __fastcall TForm1::AppMessage(tagMSG &Msg, bool &Handled)
{
if (Msg.message == WM_FILEREADY)
{
Memo1->Lines->LoadFromFile(AnsiString((char *)Msg.lParam));
Handled = true; // не отправлять дальше по-цепочке (обработано)
}
}
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *Button1;
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
void __fastcall AppMessage(tagMSG &Msg, bool &Handled); // определяем функцию, которая будет ловить сообщения
};
// cpp
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
Application->OnMessage = AppMessage; // переопределяем функцию, которая будет ловить сообщения
}
const WM_FILEREADY = WM_USER + 2000;
void __fastcall TForm1::AppMessage(tagMSG &Msg, bool &Handled)
{
if (Msg.message == WM_FILEREADY)
{
Memo1->Lines->LoadFromFile(AnsiString((char *)Msg.lParam));
Handled = true; // не отправлять дальше по-цепочке (обработано)
}
}
Автор ответа: SABROG
Как удалить строку/столбец в StrinGrid?
1. Ответ:
Удаление строки присутствует в TCustomGrid: : DeleteRow(int ARow), но эта функция закрыта(protected) для свободного использования.
Пример:
Код:
class TPublicGrid: public TStringGrid
{
public:
using TStringGrid::DeleteRow;
};
...
((TPublicGrid*)StringGrid1)->DeleteRow(2);
{
public:
using TStringGrid::DeleteRow;
};
...
((TPublicGrid*)StringGrid1)->DeleteRow(2);
или так
Пример:
Код:
class PACKAGE TMyStringGrid: public TStringGrid
{
private:
protected:
public:
__fastcall TMyStringGrid(Classes::TComponent* AOwner):
TStringGrid(AOwner){};
void _fastcall MoveRow(int from,int to){RowMoved(from,to); }
void _fastcall RowDelete(int arow){DeleteRow(arow);}
void _fastcall InsertRow(int arow){RowCount++; RowMoved(RowCount-1,arow);}
};
{
private:
protected:
public:
__fastcall TMyStringGrid(Classes::TComponent* AOwner):
TStringGrid(AOwner){};
void _fastcall MoveRow(int from,int to){RowMoved(from,to); }
void _fastcall RowDelete(int arow){DeleteRow(arow);}
void _fastcall InsertRow(int arow){RowCount++; RowMoved(RowCount-1,arow);}
};
Автор ответа: lena_ki
2. Ответ:
Удалить в компоненте TStringGrid произвольную строку или столбец нельзя, только последнюю(ий) и поэтому получается следующее...
Пример:
Код:
//удалить колонку...
void RemoveCol(TStringGrid* StringGrid, int Index)
{
assert(StringGrid != NULL);
//откл. перерисовку...
SNDMSG(StringGrid->Handle, WM_SETREDRAW, false, 0);
try
{
const int col_count = StringGrid->ColCount;
// смещаем стобцы на один влево
for (int col = Index; col < col_count - 1; ++col)
{
StringGrid->Cols[col] = StringGrid->Cols[col + 1];
}
// удаляем последнюю колонку...
StringGrid->ColCount = col_count -1;
}
__finally
{
SNDMSG(StringGrid->Handle, WM_SETREDRAW, true, 0);
}
// вычисляем область для перерисовки...
RECT R = StringGrid->CellRect(0, Index);
InflateRect(&R, StringGrid->Width, StringGrid->Height);
//и обновляем ее...
InvalidateRect(StringGrid->Handle, &R, false);
}
//-----------------------------------------------------------------------------
void RemoveCol(TStringGrid* StringGrid, int Index)
{
assert(StringGrid != NULL);
//откл. перерисовку...
SNDMSG(StringGrid->Handle, WM_SETREDRAW, false, 0);
try
{
const int col_count = StringGrid->ColCount;
// смещаем стобцы на один влево
for (int col = Index; col < col_count - 1; ++col)
{
StringGrid->Cols[col] = StringGrid->Cols[col + 1];
}
// удаляем последнюю колонку...
StringGrid->ColCount = col_count -1;
}
__finally
{
SNDMSG(StringGrid->Handle, WM_SETREDRAW, true, 0);
}
// вычисляем область для перерисовки...
RECT R = StringGrid->CellRect(0, Index);
InflateRect(&R, StringGrid->Width, StringGrid->Height);
//и обновляем ее...
InvalidateRect(StringGrid->Handle, &R, false);
}
//-----------------------------------------------------------------------------
Автор ответа: ***