So The question is, "How do you toggle the caret in any edit control, from a line to a block, based on the Insert key?"
A little history:
1. I've been able to capture, read and insert additional messages to RichEdit's WM_SETFOCUS message.
2. I've been able to destroy RichEdit's caret on entry, but with a mouse click, it's back.
3. I've never been able to alter the caret shape in any VCL control in Delphi or CBuilder. Only in straight "C" API programs.
You'd have thought the Borland team would have made this a property of TEdit, and therefore all edit controls since it's almost expected when the user toggles the Ins key into overtype. I mean, you wouldn't want the world to be able to say, "I can spot a 'Borland-Written' program a mile away. They're the one's where the caret always stays the same shape."
Ok, so I thought if I ruffled someone's feathers, we'd have a component within the week...
--
Rick Malik
"Visit the C++ Builder Hobby Pages"
http://home.pacbell.net/rmfci/bcbhp.htm
Balance = Copied letter from cbp-threads:
Rick,
I finally got the caret stuff to work properly!!!
Many thanks to Charlie Calvert's new book,
"C++ Builder 3 Unleashed". He had the directions that
corrected the problem where my SetFocus/KillFocus handlers
were crashing my PC.
Anyway, here's the code I came up with. Use it as you
will. If you find any problems, let me know.
(Note: I'm descending from TCustomPanel instead of
TRichEdit, so you'll need to change that part.)
program.h:
==========
private:
void __fastcall WMSetFocus(TWMSetFocus &Message);
void __fastcall WMKillFocus(TWMKillFocus &Message);
// Caret control functions.
bool __fastcall HidetheCaret (void);
void __fastcall NewCaret (void);
void __fastcall SetCaretPosition (int newcol, int newline);
void __fastcall ShowtheCaret (void);
void __fastcall UpdatetheCaret (void);
// Last declaration in the class definition in the header file.
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_SETFOCUS,TWMSetFocus,WMSetFocus)
MESSAGE_HANDLER(WM_KILLFOCUS,TWMKillFocus,WMKillFocus)
END_MESSAGE_MAP(TCustomPanel)
program.cpp:
============
//---------------------------------------------------------------------
------
void __fastcall TgpCustomTerminal::WMSetFocus(TWMSetFocus &Message)
{
TCustomPanel::Dispatch(&Message);
if (!(ComponentState.Contains(csDesigning)))
{
NewCaret();
CaretHideCount = 0;
SetCaretPos (((FCaretPoint % FLineWidth) * FCharWidth) + SideBorder,
((FCaretPoint / FLineWidth) * FCharHeight) +
TopBorder);
ShowCaret(Handle);
Cursor = crIBeam;
}
}
//---------------------------------------------------------------------
------
void __fastcall TgpCustomTerminal::WMKillFocus(TWMKillFocus &Message)
{
if (!(ComponentState.Contains(csDesigning)))
{
Cursor = crDefault;
DestroyCaret();
}
TCustomPanel::Dispatch(&Message);
}
//---------------------------------------------------------------------
------
bool __fastcall TgpCustomTerminal::HidetheCaret (void)
{
// Hides the caret and increments a counter so we know how many
// times this has been done. Returns the boolean result of the
// HideCaret call.
bool
havecaret = HideCaret(NULL);
if (havecaret)
++CaretHideCount;
return havecaret;
}
//---------------------------------------------------------------------
------
void __fastcall TgpCustomTerminal::NewCaret (void)
{
// Creates a new caret based upon the edit mode and the font
// characteristics.
if (FEditMode == edOver)
// Block style caret.
CreateCaret (Handle, (HBITMAP)1, FCharWidth, FOrigCharHeight);
else
// Thin vertical line caret.
CreateCaret (Handle, NULL, 0, FOrigCharHeight);
}
//---------------------------------------------------------------------
------
void __fastcall TgpCustomTerminal::ShowtheCaret (void)
{
// Calls ShowCaret enough times to counter previous HideCaret calls.
while (CaretHideCount > 0)
{
ShowCaret(Handle);
--CaretHideCount;
}
CaretHideCount = 0;
}
//---------------------------------------------------------------------
------
void __fastcall TgpCustomTerminal::UpdatetheCaret (void)
{
// Moves the caret image on the screen to match the current value
// of FCaretPoint and forces the caret to show itself.
// Note: This must be the ONLY procedure that moves the Caret!
// Therefore, it is also the only procedure which calls HidetheCaret
// and ShowtheCaret.
if (!Focused())
return;
if (FNoUpdate)
return;
bool
hascaret = HidetheCaret();
if ((LastEditMode != FEditMode) &&
hascaret)
{
DestroyCaret();
hascaret = false;
LastEditMode = FEditMode;
}
if (!hascaret)
NewCaret();
SetCaretPos (((FCaretPoint % FLineWidth) * FCharWidth) + SideBorder,
((FCaretPoint / FLineWidth) * FCharHeight) + TopBorder);
ShowtheCaret();
}
-------------------------------------
Name: Donald J. Gregory
E-mail:don...@gregpub.com
See our Unisys A-Series documentation:
www.gregpub.com
-------------------------------------
Stop Global Warming!
Eliminate politicians, lawyers, left-wing activists,
and all other sources of hot air!