Button that output on TEdit - c++

I'm trying to make a simple calculator with Embarcadero C++Builder. I'm still a novice. How can I extract text from a button? When I press the button, I want to see "3" on a TEdit field (for example). Surely the event is OnClick. But after that, what must I do to redirect this button to TEdit?

As you said, TButton has an OnClick event; if you want to append a certain character to the text of a TEdit:
// Somewhere declared and istantiated:
//TButton *Button1;
//TEdit *Edit1;
//----------------------------------
void __fastcall TForm1::Button1Click(TObject* Sender)
{
Edit1->Text = Edit1->Text + "3";
}

Related

Closing Popup and setting button label

I'm writing a C++ wxWidgets calculator application. I want to compress trigonometric function buttons into a single one to save on space, using what's basically a split button. If you left click on it, the current option is used. If you right click, a popup menu is opened, which contains all the buttons; when you click on one of them, it is used and the big button changes.
I've been suggested to use wxComboBox and other stuff for this job, but I preferred using wxPopupTransientWindow because this way I can display the buttons in a grid, making everything - in my opinion - neater.
Problem is, when I choose an option from the menu, the main button's ID changes (because when I reopen the menu the previously clicked button is light up as its ID and the big button's ID match), but the label does not. Furthermore, the popup is supposed to close itself when you left click on one of the buttons, but it does not.
This is the code for the custom button in the popup which is supposed to do all that stuff:
void expandButton::mouseReleased(wxMouseEvent& evt)
{
if (pressed) {
pressed = false;
paintNow();
wxWindow* mBtn = this->GetParent()->GetParent();
mBtn->SetLabel(this->GetLabel());
mBtn->SetId(this->GetId());
this->GetParent()->Close(true);
}
}
This is the code for the custom button in the main frame which opens up the popup (temporary setup just to test if the whole thing is working):
void ikeButton::rightClick(wxMouseEvent& evt) // CREA PANNELLO ESTENSIONE
{
if (flags & EXPANDABLE)
{
std::vector<expandMenuInfo> buttons;
buttons.push_back(expandMenuInfo(L"sin", 3001));
buttons.push_back(expandMenuInfo(L"cos", 3002));
buttons.push_back(expandMenuInfo(L"tan", 3003));
buttons.push_back(expandMenuInfo(L"arcsin", 3004));
buttons.push_back(expandMenuInfo(L"arccos", 3005));
buttons.push_back(expandMenuInfo(L"arctan", 3006));
wxPoint p = this->GetScreenPosition();
size_t sz = this->GetSize().GetHeight() / 1.15;
expandMenu* menu = new expandMenu(this, buttons, sz, wxPoint(
p.x, p.y + this->GetSize().GetHeight() + 2));
menu->SetPosition(wxPoint(
menu->GetPosition().x - ((menu->GetSize().GetWidth() - this->GetSize().GetWidth()) / 2),
menu->GetPosition().y));
menu->Popup();
}
}
Let me know if I need to show more code.
This is probably a terrible way of doing this, but this is basically the first "serious" application I'm creating using the wxWidgets framework. Any help is appreciated.
when I choose an option from the menu, the main button's ID changes
(because when I reopen the menu the previously clicked button is light
up as its ID and the big button's ID match), but the label does not.
If you're creating the popup menu like in your previous post, you had a popup window with a panel as its child and the buttons were then children of the panel layed out with a sizer.
If that's still the case, this->GetParent() and should be the panel, this->GetParent()->GetParent() should be the popup. So this->GetParent()->GetParent()->GetParent() should be the trig function button (assuming you created the popup with the trig function button as the parent).
So I think the line wxWindow* mBtn = this->GetParent()->GetParent(); should be changed to wxWindow* mBtn = this->GetParent()->GetParent()->GetParent();.
Or slightly shorter wxWindow* mBtn = this->GetGrandParent()->GetParent();;
the popup is supposed to close itself when you left click on one of
the buttons, but it does not.
It looks like wxPopupTransientWindow has a special Dismiss method that is supposed to be used to close it.
So I think the line this->GetParent()->Close(true); should be changed to this->GetGrandParent()->Dismiss(); (Assuming as above that the buttons in the popup are children pf a panel).
Alternately, if you want a solution that will work regardless of the parentage of the controls in the popup window, you could have a utility function to find the popup ancestor which would look something like this:
wxPopupTransientWindow* FindPopup(wxWindow* w)
{
wxPopupTransientWindow* popup = NULL;
while ( w != NULL )
{
popup = wxDynamicCast(w, wxPopupTransientWindow);
if ( popup )
{
break;
}
w = w->GetParent();
}
return popup;
}
This uses the wxDynamicCast function which is slightly different from the c++ dynamic_cast expression. wxDynamicCast uses wxWidgets' RTTI system to check if the given pointer can be converted to the given type.
Then the mouseReleased method could use this utility function something like this:
void expandButton::mouseReleased(wxMouseEvent& evt)
{
if (pressed) {
pressed = false;
paintNow();
wxPopupTransientWindow* popup = FindPopup(this);
if (popup ) {
wxWindow* mBtn = popup->GetParent();
mBtn->SetLabel(this->GetLabel());
mBtn->SetId(this->GetId());
mBtn->Refresh();
popup->Dismiss();
}
}
}
I'm not sure why you're setting trig function button to have a new id, but I assume you have a reason.
To make the SetLabel method work in your custom button class, I think the easist thing is to call the SetLabel() method in the button's constructor. This will store the string passed to the constructor in the button's internal label member.
Based on other questions, I think the ikeButton constructor looks something like this:
ikeButton::ikeButton(wxFrame* parent, wxWindowID id, wxString text,...
{
...
this->text = text;
To store the label, you would need to change the line this->text = text; to
SetLabel(text);
And when you draw the button, I think the method you use looks like this:
void ikeButton::render(wxDC& dc)
{
...
dc.DrawText(text, ...);
}
You would need to change, the line dc.DrawText(text, ...); to
dc.DrawText(GetLabel(), ...);
Likewise, any other references to the button's text member should be changed to GetLabel() instead.
Finally, when you set the label in the expandButton::mouseReleased method, it might be a good idea to call button's Refresh() method to force the button to redraw itself. I added that my suggestion for the mouseReleased method above.

Text Selection with CRichEditCtrl in MFC

I have CRichEditCtrl object which is read only(Text is for read and not allowed to modified). I want to provide functionality of Text Selection with Mouse for text displayed with CRichEditCtrl object.
Following Code is working to capture event for Left Mouse Button - DOWN & UP
BOOL CReportFormView::PreTranslateMessage(MSG* pMsg)
{
if (m_EditNs->GetFocus()!=NULL)
{
switch (pMsg->message)
{
case WM_LBUTTONDOWN:
return TRUE;
case WM_LBUTTONUP:
return TRUE;
}
}
}
Now looking for some code to write in case block which will highlight selected text. I want to know if there is any API available for CRichEditCtrl object which help to track at which location user pressed Left Mouse Button and released
You could use member function CString strText = m_myRichEditCtrl.GetSelText(); or some other member function. Like GetSel() just a suggestion.
I think you will need to use the EM_CHARFROMPOS message. ex. some form of this:
POINTL pt { x,y }; // ... screen coordinates to test relative to edit
DWORD info = m_EditNS->SendMessage(EM_CHARFROMPOS, 0, pt);
int charIndex = LOWORD(info);
int line = HIWORD(info);
After that, set the selection with normal selection methods.
https://msdn.microsoft.com/en-us/library/windows/desktop/bb761566(v=vs.85).aspx

How to get the released button inside MouseReleaseEvent in Qt

In MouseReleaseEvent(QMouseEvent *e), is there a way to know which button was released without using a new variable ? I mean something like in the MousePressEvent(QMouseEvent *e) with e.buttons().
I tried e.buttons() in the releaseEvent it's not working (which is logical).
e is already a variable. Just use:
void mouseReleaseEvent(QMouseEvent *e)
{
if (e->button() == Qt::LeftButton) // Left button...
{
// Do something related to the left button
}
else if (e->button() == Qt::RightButton) // Right button...
{
// Do something related to the right button
}
else if (e->button() == Qt::MidButton) // Middle button...
{
// Do something related to the middle button
}
}
A switch statement also works. I prefer the series of if -- else if because they make it easier to handle evente modifiers, i.e., e->modifiers() in order to check for alt or control clicks. The series of if's is short enough not to create any burden on the program.
EDIT: Note that you should use the button() function, not its plural buttons() version. See the explanation in #Merlin069 answer.
The problem in the posted code is this: -
if(e->buttons() & Qt::LeftButton)
As the Qt documentation states for the release event: -
... For mouse release events this excludes the button that caused the event.
The buttons() function will return the current state of the buttons, so since this is a release event, the code will return false, as it's no longer pressed.
However, the documentation for the button() function states:-
Returns the button that caused the event.
So you can use the button() function here.

Catch ESC key press event when editing a QTreeWidgetItem

I'm developing a project in Qt. I have a QTreeWidget(filesTreeWidget) whith some file names and a button for creating a file. The Create button adds to the filesTreeWidget a new item(the item's text is "") who is edited for choosing a name. When I press ENTER, the filename is send through a socket to the server. The problem comes when I press ESC because the filename remains "" and is not send to the server. I tried to overwrite the keyPressEvent but is not working. Any ideas? I need to catch the ESC press event when I'm editing the item.
You can subclass QTreeWidget, and reimplement QTreeView::keyPressEvent like so:
void MyTreeWidget::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Escape)
{
// handle the key press, perhaps giving the item text a default value
event->accept();
}
else
{
QTreeView::keyPressEvent(event); // call the default implementation
}
}
There might be more elegant ways to achieve what you want, but this should be pretty easy. For example, if you really don't want to subclass, you can install an event filter, but I don't like doing that especially for "big" classes with lots of events because it's relatively expensive.
Implement keyPressEvent function as following:
void TestTreeWidget::keyPressEvent(QKeyEvent *event)
{
switch (event->key())
{
case Qt::Key_Escape:
{
escapeKeyPressEventHandler();
event->accept();
break;
}
default:
QTreeWidget::keyPressEvent(event);
}
}
TestTreeWidget::escapeKeyPressEventHandler()
{
// work with your QTreeWidgetItem here
}

how to write a function Click() for dynamic created button?

Trying to write a simple VCL program for educating purposes (dynamicly created forms, controls etc). Have such a sample code:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TForm* formQuiz = new TForm(this);
formQuiz->BorderIcons = TBorderIcons() << biSystemMenu >> biMinimize >> biMaximize;
formQuiz->Position = TPosition::poDesktopCenter;
formQuiz->Width = 250;
formQuiz->Height = 250;
formQuiz->Visible = true;
TButton* btnDecToBin = new TButton(formQuiz);
btnDecToBin->Parent = formQuiz;
btnDecToBin->Left = 88;
btnDecToBin->Top = 28;
btnDecToBin->Caption = "Dec to Bin";
btnDecToBin->Visible = true;
}
I wonder how can i write a function for dynamic created button, so it would be called when the button is clicked. In this example i need a 'btnDecToBin->Click();' func but i don't know where should i place it.
Inside 'void __fastcall TForm1::Button1Click(TObject *Sender){}' ?
I will appreciate any input, some keywords for google too.
You could do two things, you could either create an action and associate it with the button, or you could make a function like so:
void __fastcall TForm1::DynButtonClick(TObject *Sender)
{
// Find out which button was pressed:
TButton *btn = dynamic_cast<TButton *>(Sender);
if (btn)
{
// Do action here with button (btn).
}
}
You bind it to the button instance by setting the OnClick property btnDecToBin->OnClick = DynButtonClick please note that the function is inside the form Form1. This will work due to the nature of closures (compiler specific addition). The problem comes if you delete Form1 before formQuiz without removing the reference to the click event. In many ways it might be a more clean solution to use an Action in this case.
Edit: On other way to do this, if you have a standard layout for your quizforms, you could make a custom TQuizForm class inheriting from TForm. In this way you wouldn't have to bind the event each time you create the form.
all buttons have the normal "events" you just need to reference them to the method you will deal with the event.
example:
...
btnDecToBin->OnClick = &Test;
-- and add a additional method to .cpp
void __fastcall TForm1::Test(TObject *Sender)
{
TButton *btn = dynamic_cast<TButton *>(Sender);
if (btn->name == "your_button_name"){
// Do action here with button (btn).
}
}
and on .h
void __fastcall TForm1::Test(TObject *Sender);
reference the button either by the tag or name. I usually use a array of buttons that I create dynamically. ALWAYS sanity check your "sender" by casting it. There are other ways to hack info from the object but they are a path to heartache... LOL.