|
Property editors Property editor for AnsiString or any non VCL data types
............. ............. class PACKAGE TTestComponent : public TComponent { private: protected:
AnsiString FTestProperty;
public: __fastcall TTestComponent(TComponent* Owner); __published:
__property AnsiString TestProperty = { read = FTestProperty, write = FTestProperty }; };
............. ............. namespace Testcomponent { void __fastcall PACKAGE Register()
{ TComponentClass classes[1] = {__classid(TTestComponent)}; RegisterComponents("BMitov", classes, 0);
PPropInfo PropInfo; PropInfo = ::GetPropInfo ( __typeinfo(TTestComponent), "TestProperty" );
RegisterPropertyEditor( *( PropInfo->PropType ), __classid(TTestComponent), "TestProperty", __classid(TStringPropertyEditor) ); } }
General Creating component at run time
TEdit *Edit = new TEdit ( this );
Edit->Parent = this;
Need of Application handler ( Instance )
There is a global variable :
extern HINSTANCE HInstance;
TRichEdit
Getting TrichEdit caret position
int CaretLine = RichEdit1->Perform (EM_LINEFROMCHAR, -1, 0 ) + 1; int
CaretPos = RichEdit1->SelStart - RichEdit1->Perform ( EM_LINEINDEX, -1, 0 ) + 1;
Showing ( Scrolling to ) the current selection
RichEdit1->Perform ( EM_SCROLLCARET, 0, 0 );
Selecting a line
RichEdit1
->SelStart = RichEdit1->Perform ( EM_LINEINDEX, LineNumber, 0 ); RichEdit1->SelLength = RichEdit1
->Lines->Strings [ LineNumber ] . Length ();
TStringGrid
Using Objects property
Objects is general purpose 2 dimensional virtual array pointers. You can use this to associate any object descend of TObject
with a cell on Your Grid. However the grid doesn’t care about is it an TObject descended object or not, so You can even assign any kind of object with some casting.
How to use this ?
// First of all we do need of class to store our data :
class TMyObject :
public TObject { public : int Value; AnsiString Name;
public : __fastcall TMyObject() {} };
// Second we do need of kind of container for our data. A
good one could be an STL container as list. So in our Unit1.h file :
#include <list.h> using namespace std;
class TForm1 : public TForm { public: // User declarations list <TObject*> ObjectsList;
…… ………. ………… private: // User declarations void __fastcall
AsignObjects ();
public: // User declarations __fastcall TForm1(TComponent* Owner);
__fastcall ~TForm1(); };
//---------------------------------------------------------------------------
// Now let’s write the code : __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{ AsignObjects (); }
//---------------------------------------------------------------------------
// We should release the allocated memory for our objects :
__fastcall TForm1::~TForm1() { list
<TObject *>::iterator Iter; for ( Iter = ObjectsList.begin (); Iter != ObjectsList.end (); Iter ++ )
delete *Iter; }
//---------------------------------------------------------------------------
// The real assignment :
void __fastcall TForm1::AsignObjects () { for ( int x = 0; x
< StringGrid1->ColCount; x ++ ) for ( int y = 0; y < StringGrid1->RowCount; y ++ )
{ TMyObject *MyData = new TMyObject; MyData->Value = 20 + x + y
; MyData->Name = (AnsiString)"Objects [ " + x + " ][ " + y + " ]";
ObjectsList.push_back ( MyData ); StringGrid1->Cells[ x ][ y ] = (AnsiString)
"Cell " + x + " " + y; StringGrid1->Objects [ x ][ y ] = MyData;
} }
//---------------------------------------------------------------------------
// Add a SelectCell event on Your StringGrid :
void __fastcall TForm1::StringGrid1SelectCell(TObject *Sender, long Col, long Row
, bool &CanSelect) { Label3->Caption = (( TMyObject * ) StringGrid1->Objects [ Col ][ Row
] )->Value; Label4->Caption = (( TMyObject * ) StringGrid1->Objects [ Col ][ Row ] )->Name;
}
//---------------------------------------------------------------------------
That’s all. Enjoy.
AnsiString
Using AnsiString
AnsiString: AnsiString MyString; //the same as String MyString;
MyString = "we are building ";
String MySecondString = "up a long string"; MyString += MySecondString; //adding string to string
MyString = AnsiSttring ( ”This ” ) + 4 + “ is an integer value, and this \‘” + MySecondString + “\’ is an AnsiString.”;
AnsiString UpperCaseString = MyString.UpperCase ();
Using AnsiString as char *
AnsiString AString = “Hello World”;
char * str = AString.c_str ();
Accesing particular character within a AnsiString
AnsiString AString = “Hello World”;
char ch = AString [ 2 ]; // returns ‘e’ char ch = AString.c_str [ 2 ]; // returns ‘l’
TTreeView
Processing double click only wehen the click is over an item
If You would like to perform an option, only when You are double clicking on a ListView item ( not in the entire
ListView area ) use :
1. In Your Form1.h in the protected area, put :
bool LastTreeViewLabelHit;
2. In the Form1.cpp :
//--------------------------------------------------------------------------- void __fastcall TMainForm::TreeView1MouseDown(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y) { THitTests MyHitTest; MyHitTest = MainTreeView->GetHitTestInfoAt( X, Y );
LastTreeViewLabelHit = ( MyHitTest.Contains ( htOnLabel ) ); } //--------------------------------------------------------------------------- void __fastcall
TMainForm::TreeView1DblClick ( TObject *Sender ) { if ( MainTreeView->Selected ) if ( LastTreeViewLabelHit )
{ // Do something with MainTreeView->Selected }
LastTreeViewLabelHit = false; }
TListView
Higliting the entire item in the ListView
Immidiately afer updating the list view :
#define LVS_EX_FULLROWSELECT 0x000000020 #define LVM_SETEXTENDEDLISTVIEWSTYLE (LVM_FIRST + 54)
DvlListView->Perform ( LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT );
Don’t forget to do the same every time after updating the List View.
TForm
Browsing and closing dynamicaly created forms with Show
In the FIRST form :
void __fastcall TForm1::Button1Click(TObject *Sender) { TForm2 Form2 = new TForm2 ( Application ); Form2->Show (); }
In the SECOND form :
void __fastcall TForm2::FormClose(TObject *Sender, TCloseAction &Action) { Action = caFree; }
Move to the next component using ENTER
Set the TForm1->KeyPreview = true.
void __fastcall TForm1::FormKeyPress(TObject *Sender, char &Key) { if ( Key == '\r' ) {
SelectNext( ActiveControl, true, true ); Key = '\0'; } }
TStatusBar Putting a ProgressBar on the StatusBar
ProgressBar = new TProgressBar ( StatusBar ); ProgressBar->Parent = StatusBar;
ProgressBar->Position = 0;
ProgressBar->Visible = false;
void __fastcall TMainForm::StatusBarResize(TObject *Sender) { int Size = StatusBar->Width;
for ( int i = 1; i < StatusBar->Panels->Count; i++ ) Size -= StatusBar->Panels->Items[i]->Width;
//resize the first panel based on the form width
StatusBar->Panels->Items[ 0 ]->Width = Size; RECT Rect; StatusBar->Perform ( SB_GETRECT, 0, (LPARAM)&Rect );
ProgressBar->Top = Rect.top;
ProgressBar->Left = Rect.left; ProgressBar->Width = StatusBar->Panels->Items [ 0 ]->Width; ProgressBar->Height = Rect.bottom - Rect.top; }
Drawing a bitmap on the StatusBar
Add a StatusBar and TImageList. Create a StatusPanel in the status bar with OwnerDraw style.
void __fastcall TForm1::StatusBar1DrawPanel(TStatusBar *StatusBar, TStatusPanel *Panel, const TRect &Rect) {
TCanvas & c = *StatusBar->Canvas;
if ( Panel->Index == 0 ) // 0 - this is the first status panel. { Graphics::TBitmap *Image = new Graphics::TBitmap;
ImageList1->GetBitmap( 0, Image ); c.Draw ( Rect.Left, Rect.Top, Image ); delete Image; } }
TPageControl
Ataching a form to a TabSheet
Create a Tform named Form2. Set Form2->BorderStyle = bsNone.
TPanel *Panel = new TPanel ( TabSheet1 );
Panel->Parent = TabSheet1; Panel->Align = alClient;
TForm2 *form = new TForm2 ( Panel, this, AppData ); form->Parent = Panel; form->Left = 0;
form->Top = 0; form->Visible = true;
Panel->OnResize = OnContainerPanelResize;
........ .........
void __fastcall TMainForm::OnContainerPanelResize(TObject *Sender) { TPanel * Panel = dynamic_cast<TPanel *>( Sender ); if ( Panel->ControlCount ) {
Panel->Controls[ 0 ]->Left = 0; Panel->Controls[ 0 ]->Top = 0; Panel->Controls[ 0 ]->Width = Panel->Width;
Panel->Controls[ 0 ]->Height = Panel->Height; } }
Catching messages Using message map
class TForm1 : public TForm { ...... ...... void __fastcall EraseBkg(TMessage& Msg);
void __fastcall WmMove(TMessage& Msg); ...... ...... BEGIN_MESSAGE_MAP MESSAGE_HANDLER( WM_ERASEBKGND,TMessage,EraseBkg ) MESSAGE_HANDLER( WM_MOVE,TMessage,WmMove )
END_MESSAGE_MAP(TForm) ...... ...... };
...... ......
void __fastcall TForm1::WmMove (TMessage& Msg) { ...... ...... TForm::Dispatch ( &Msg ); // Default.
...... ...... }
void __fastcall TForm1::EraseBkg (TMessage& Msg) { // Prevent the form from procesing the WM_ERASEBKGND }
Using WndProc
class TForm1 : public TForm { ...... ...... virtual void __fastcall WndProc(Messages::TMessage &Message); ...... ......
};
...... ......
void __fastcall TForm1::WndProc(Messages::TMessage &Message) { if ( Message.Msg == WM_PAINT ) {
...... ...... } TForm::WndProc( Message ); // Default. }
Catching messages of another object
class TForm1 : public TForm { ...... TMemo *Memo1; ...... ...... int (__stdcall *OldHookComponentProc) ();
int (__stdcall *NewHookComponentProc) ();
HWND OwnerHandle; ...... ...... void __fastcall HookComponentProc(TMessage &aMsg);
void __fastcall HookComponent(); void __fastcall UnhookComponent(); ...... ...... __fastcall TForm1 (TComponent* _Owner) ; __fastcall ~TForm1(); ...... ...... };
//--------------------------------------------------------------------------- __fastcall TForm1::TForm1 (TComponent* _Owner) : TCustomPanel(_Owner),
NewHookComponentProc ( NULL ) { HookComponent(); } //--------------------------------------------------------------------------- __fastcall TForm1::~TForm1() {
if ( NewHookComponentProc ) UnhookForm(); } //--------------------------------------------------------------------------- void __fastcall TForm1::HookComponent() {
OwnerHandle = Memo1->Handle;
OldHookComponentProc = (int (__stdcall *)()) GetWindowLong(OwnerHandle, GWL_WNDPROC);
NewHookComponentProc = (int (__stdcall *)()) MakeObjectInstance(HookComponentProc);
SetWindowLong(OwnerHandle, GWL_WNDPROC, (long) NewHookComponentProc); }
//--------------------------------------------------------------------------- void __fastcall TForm1::UnhookComponent() { SetWindowLong(OwnerHandle, GWL_WNDPROC, (long) OldHookComponentProc);
if (NewComponentFormProc) FreeObjectInstance(NewComponentFormProc);
NewHookComponentProc = NULL; }
//--------------------------------------------------------------------------- void __fastcall TForm1::HookComponentProc( TMessage &aMsg ) { switch ( aMsg.Msg ) {
case WM_SHOWWINDOW: { // Memo1 -> WM_SHOWWINDOW . } case WM_SIZE:
{ // Memo1 -> WM_SIZE . } }
// Default.
aMsg.Result = CallWindowProc(OldHookFormProc, OwnerHandle,
aMsg.Msg, aMsg.WParam, aMsg.LParam);
}
//---------------------------------------------------------------------------
TFont Saving and restoring TFont into/from a stream (File).
..... .....
// Save to a file stream
TFileStream *Fstr = new TFileStream ("C:\\Boza.txt", fmOpenReadWrite | fmCreate ); Fstr->Write ( Label1->Font, Label1->Font->InstanceSize () ); delete Fstr;
..... .....
// Load from a file stream Byte *Buffer = new Byte [ InstanceSize(__classid(TFont)) ];
TFileStream *Fstr1 = new TFileStream ("C:\\Boza.txt", fmOpenReadWrite );
Fstr1->Read ( Buffer, InstanceSize(__classid(TFont)) );
delete Fstr1;
Label2->Font->Assign ( (TFont *)Buffer );
delete Buffer;
..... .....
|