How to manually get TMouseButton in C++Builder - c++builder

I am using C++Builder from Embarcadero Technology. The built in OnClick event handler does not identify if the mouse click is the left or right button. Is there a function I can call to manually fill the values for TMouseButton. Below is the OnClick event handler?
void __fastcall TForm::ListBox1Click(TObject *Sender)
{
TMouseButton Button;
Button = ???
}

As others have mentioned, you can use the OnMouseDown event to remember the current mouse button state for use in OnClick, eg.
private:
bool LButtonDown;
bool RButtonDown;
...
void __fastcall TForm1::ListBox1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y)
{
switch (Button) {
case mbLeft:
LButtonDown = true;
break;
case mbRight:
RButtonDown = true;
break;
}
}
void __fastcall TForm1::ListBox1MouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y)
{
switch (Button) {
case mbLeft:
LButtonDown = false;
break;
case mbRight:
RButtonDown = false;
break;
}
}
void __fastcall TForm::ListBox1Click(TObject *Sender)
{
if (LButtonDown) ...
if (RButtonDown) ...
}
If you don't want to do that way, you can use the Win32 API GetKeyState() or GetAsyncKeyState() function to query the current state of the mouse's left and right buttons, using the VK_LBUTTON and VK_RBUTTON virtual key codes, eg:
void __fastcall TForm::ListBox1Click(TObject *Sender)
{
if (GetKeyState(VK_LBUTTON)) ...
if (GetKeyState(VK_RBUTTON)) ...
}

The correct event to use for details of mouse click events is OnMouseDown (also OnMouseUp and OnMouseMove).
Override the event and then implement MouseDown event like this
void __fastcall TMyListView::MouseDown(System::Uitypes::TMouseButton Button, System::Classes::TShiftState Shift, int X, int Y)
{
if (Button == mbLeft){
}
if (Button == mbRight){
}
}
See also Vcl.Controls.TControl.OnMouseDown in Embarcadero's documentation.

Related

Firemonkey: How do I use a TComboBox in a TStringGrid to make it work from the keyboard?

TComboBox in TStringGrid does not work when used from the keyboard. It does not update the Cells value.
I expected it to work from the keyboard when it works when I use the mouse. How should I change the code to make it work from the keyboard? Or is it a dead case?
Thanks Mika
void __fastcall TForm1::ChangeStringGridComboBox(TObject* Sender)
{
TComboBox* combobox = dynamic_cast<TComboBox*>(Sender);
if (combobox && combobox->ItemIndex > -1) {
StringGrid1->Cells[StringGrid1->Col][StringGrid1->Row] =
combobox->Items->Strings[combobox->ItemIndex];
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::StringGrid1CreateCustomEditor(
TObject* Sender, TColumn* const Column, TStyledControl*&Control)
{
TComboBox* combobox = new TComboBox(this);
if (Column == Column1) {
Control = combobox;
combobox->Items->Assign(Memo1->Lines);
combobox->ItemIndex = combobox->Items->IndexOf(
StringGrid1->Cells[StringGrid1->Col][StringGrid1->Row]);
if (combobox->ItemIndex > -1) {
StringGrid1->Cells[StringGrid1->Col][StringGrid1->Row] =
combobox->Items->Strings[combobox->ItemIndex];
}
combobox->OnChange = &ChangeStringGridComboBox;
}
}
From Firemonkey: How do I use a TComboBox in a TStringGrid to make it work from the keyboard?:
To use a TComboBox in a TStringGrid and make it work from the keyboard, you can follow these steps:
Place a TComboBox component on your form and set its Parent property to the TStringGrid.
Set the TComboBox's Visible property to False.
Handle the TStringGrid's OnSelectCell event. In the event handler, check if the current column of the selected cell is the column that the TComboBox is associated with. If it is, set the TComboBox's Left and Top properties to the coordinates of the selected cell, and set its Visible property to True.
Handle the TStringGrid's OnKeyPress event. In the event handler, check if the key pressed is the down arrow key. If it is, and the TComboBox is visible, set the focus to the TComboBox.
Handle the TComboBox's OnExit event. In the event handler, set the TComboBox's Visible property to False, and set the focus back to the TStringGrid.
In the TComboBox's OnSelect event, you can get the selected value and assign it to the selected cell of the TStringGrid.
You can also create a custom component that inherits from TStringGrid and add the TComboBox and the necessary events to it.
Since you are creating the TComboBox as a custom InplaceEditor, most of that should already be handled for you by the TStringGrid. All you are really missing is the Key Press handler, eg:
// Unlike VCL, FMX does not expose access to TStringGrid's
// active Editor, so keep track of it manually...
protected:
void __fastcall Notification(TComponent* AComponent, TOperation Operation) override;
private:
TComboBox *myComboBox;
...
void __fastcall TForm1::StringGrid1CreateCustomEditor(
TObject* Sender, TColumn* const Column, TStyledControl* &Control)
{
if (Column == Column1) {
myComboBox = new TComboBox(this);
myComboBox->Items->Assign(Memo1->Lines);
myComboBox->ItemIndex = myComboBox->Items->IndexOf(
StringGrid1->Cells[StringGrid1->Col][StringGrid1->Row]);
myComboBox->OnChange = &ChangeStringGridComboBox;
Control = myComboBox;
}
}
void __fastcall TForm1::ChangeStringGridComboBox(TObject* Sender)
{
if (myComboBox->ItemIndex > -1) {
StringGrid1->Cells[StringGrid1->Col][StringGrid1->Row] =
myComboBox->Items->Strings[myComboBox->ItemIndex];
}
}
void __fastcall TForm1::StringGrid1KeyPress(
TObject* Sender, Word &Key, WideChar &KeyChar, TShiftState Shift)
{
if ((Key == vkDown) && StringGrid1->EditorMode)
{
Key = 0;
myComboBox->SetFocus();
}
}
void __fastcall TForm1::Notification(TComponent* AComponent, TOperation Operation)
{
TForm::Notification(AComponent, Operation);
if ((Operation == TOperation::opRemove) && (AComponent == myComboBox)) {
myComboBox = nullptr;
}
}
With the following changes, TComboBox works fine:
ChangeStringGridComboBox
{
...
temp = myComboBox->Items->Strings[myComboBox->ItemIndex];
}
StringGridEditingDone
{
if (Column1 == StringGrid1->ColumnByIndex(ACol) && temp.Length()) {
StringGrid1->Cells[StringGrid1->Col][StringGrid1->Row] = temp;
temp = "";}
}

Using StyleHook in C++ Builder

I need to create a style hook for TEdit in C++ Builder XE7, in order to override the style color management, as the following Delphi example. Could somebody post a complete example in C++ Builder (hook unit, registration and example form)? Thanks!
A translation of the Delphi example would look something like this:
class TEditStyleHookColor : public TEditStyleHook
{
typedef TEditStyleHook inherited;
private:
void UpdateColors();
protected:
virtual void __fastcall WndProc(TMessage &Message);
public:
__fastcall TEditStyleHookColor(TWinControl *AControl);
};
#include <Vcl.Styles.hpp>
class TWinControlH : public TWinControl {};
__fastcall TEditStyleHookColor::TEditStyleHookColor(TWinControl *AControl)
: TEditStyleHook(AControl)
{
//call the UpdateColors method to use the custom colors
UpdateColors();
};
//Here you set the colors of the style hook
void TEditStyleHookColor::UpdateColors()
{
if (Control->Enabled)
{
Brush->Color = (static_cast<TWinControlH*>(Control)->Color; //use the Control color
FontColor = static_cast<TWinControlH*>(Control)->Font->Color;//use the Control font color
}
else
{
//if the control is disabled use the colors of the style
TCustomStyleServices *LStyle = StyleServices();
Brush->Color = LStyle->GetStyleColor(scEditDisabled);
FontColor = LStyle->GetStyleFontColor(sfEditBoxTextDisabled);
}
}
//Handle the messages of the control
void __fastcall TEditStyleHookColor::WndProc(TMessage &Message)
{
switch (Message.Msg)
{
case CN_CTLCOLORMSGBOX:
case CN_CTLCOLORSCROLLBAR:
case CN_CTLCOLORSTATIC:
{
//Get the colors
UpdateColors();
SetTextColor(reinterpret_cast<HDC>(Message.WParam), ColorToRGB(FontColor));
SetBkColor(reinterpret_cast<HDC>(Message.WParam), ColorToRGB(Brush->Color));
Message.Result = reinterpret_cast<LRESULT>(Brush->Handle);
Handled = true;
break;
}
case CM_ENABLEDCHANGED:
{
//Get the colors
UpdateColors();
Handled = false;
break;
}
default:
inherited::WndProc(Message);
break;
}
}
...
TStyleManager::Engine->RegisterStyleHook(__classid(TEdit), __classid(TEditStyleHookColor));
TStyleManager::Engine->RegisterStyleHook(__classid(TMaskEdit), __classid(TEditStyleHookColor));
TStyleManager::Engine->RegisterStyleHook(__classid(TLabeledEdit), __classid(TEditStyleHookColor));
TStyleManager::Engine->RegisterStyleHook(__classid(TButtonedEdit), __classid(TEditStyleHookColor));

How to check if a component is TEdit type in c++builder?

How do I check through all the components of a form and verify that components are of type TEdit?
You can use the dynamic_cast operator.
Excuse me if I'm wrong, but won't embarcadero automatically add all form-component object pointers to the class definition ( in the header file )..
Such as:
class TFormSomeForm : public TForm
{
__published:
TEdit *SomeEditBox;
TEdit *AnotherEditBox;
...
}
Meaning that you can tell from the header which components are of type TEdit.
Or you can click on the components in the Design View and the Object Inspector will show the type.
My function sets Text property of all edits in a TWinControl and its children.
void __fastcall SetEditsText(TWinControl* winControl, UnicodeString editsText)
{
for (int c = 0; c < winControl->ControlCount; c++)
{
TControl* ctrl = winControl->Controls[c];
TWinControl* wc = dynamic_cast<TWinControl*>(ctrl);
// Check if it's grouping component
if (wc != NULL)
{
// Set edits of children
SetEditsText(wc, editsText);
}
else
{
if (ctrl->ClassType() == __classid(TEdit))
{
TEdit* ecomp = (TEdit*) ctrl;
ecomp->Text = editsText;
}
}
}
}
Using:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
SetEditsText(form1, ""); // Clear all edits
}

Not receiving WM_NCMBUTTONDOWN on title bar

I am trying to create a mechanism to allow the user to right click and drag on a toolbar in order to move a window...
This is proving very difficult:
I am currently not receiving the HTCAPTION event which I have seen a really helpful post for already!
Not receiving WM_NCHitTest on title bar
The suggestion/alternative here is to use the WMNCMouseMove and inspect the HitTest to see if it is the caption.. So naively I assumed that I could extend this idea to use the WMNCMButtonDown (instead) to take me one step closer!
If this worked then I could get the type of click i.e. left, right, middle, double or single! This would have then allow me to somehow tell windows that I want this to be recognised as a drag event.
The trouble is that I never receive the WM_NCMBUTTONDOW:
void __fastcall TForm1::Dispatch( void* message )
{
switch ( static_cast<TMessage*>( message )->Msg )
{
case WM_NCHITTEST:
{
TWMNCHitTest &Message = *static_cast<TWMNCHitTest*>( message );
WMNCHitTest( Message );
break;
}
case WM_NCMOUSEMOVE:
{
TWMNCMouseMove &Message = *static_cast<TWMNCMouseMove*>( message );
WMNCMouseMove( Message );
break;
}
case WM_NCMBUTTONDOWN:
{
TWMNCMButtonDown &Message = *static_cast<TWMNCMouseMove*>( message );
WMNCMButtonDown(Message);
break;
}
default:
{
TForm::Dispatch(message);
break;
}
}
}
oes anybody have any ideas??
It is worth noting that I do in fact receive the other types of messages (WM_NCHITTEST && WM_NCMOUSEMOVE) so the mechanism is working correctly.
Please any ideas would be much appreciated!!
Thanks,
Joe
I do the following rather than override any methods.
In my .h
BEGIN_MESSAGE_MAP
{
VCL_MESSAGE_HANDLER( WM_NCHITTEST, TWMNCHitTest, WMNCHitTest );
VCL_MESSAGE_HANDLER( WM_NCCALCSIZE, TWMNCCalcSize, WMNCCalcSize );
VCL_MESSAGE_HANDLER( WM_NCPAINT, TWMNCPaint, WMNCPaint );
VCL_MESSAGE_HANDLER( WM_ERASEBKGND, TWMEraseBkgnd, StopFlicker );
VCL_MESSAGE_HANDLER( WM_NCLBUTTONDOWN, TWMNCLButtonDown, WMNCLButtonDown );
}
END_MESSAGE_MAP( TCustomPanel ) // change TCustomPanel to your parent class name
void __fastcall WMNCHitTest( Messages::TWMNCHitTest& inoutMessage );
void __fastcall WMNCCalcSize( Messages::TWMNCCalcSize& inoutMessage );
void __fastcall WMNCPaint( Messages::TWMNCPaint& inoutMessage );
void __fastcall StopFlicker( Messages::TWMEraseBkgnd& inoutMessage );
void __fastcall WMNCLButtonDown( Messages::TWMNCLButtonDown& inoutMessage );
And then I implement the code in the .cpp, for example:
void __fastcall TResizePanel::WMNCLButtonDown( Messages::TWMNCLButtonDown &inoutMessage )
{
if ( inoutMessage.HitTest == HTCLOSE )
{
delete this;
inoutMessage.Result = 0;
}
else
{
Dispatch( &inoutMessage );
}
}

how to close a popup screen in blackberry bold

hey i have displayed a pop-up screen when i click on a menu item
now i want to close that pop-up screen when user presses escape key.but it does not work and remain stuck,till i click on a button on the pop=up screen.
how can i achieve that????
filter is my pop-up screen
my code is :::
protected boolean keyChar(char c, int status, int time)
{
boolean retVal = false;
if (c == Characters.ESCAPE)
{
close();
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
//UiApplication.getUiApplication().popScreen(filter);
UiApplication.getUiApplication().
popScreen(UiApplication.getUiApplication().getActiveScreen());//(filter);
}
});
retVal = super.keyChar(c,status,time);
}
return retVal;
}
i need to override the keychar method in pop-up screen,search for escape and then close
code :
popupscreen1=new PopupScreen(myverticalfieldmanager)
{
protected boolean keyChar(char c, int status, int time)
{
if (c == Characters.ESCAPE)
close();
return super.keyChar(c, status, time);
}
};

Resources