I'm using C++ Builder in RAD Studio 10.2. I'm not sure if I asked this correctly in the title, but what I'm trying to say is that whenever I use the C++ keyword 'this', it references the Parent of the component that I'm trying to access, but not the component itself.
For example, the code below changes the Form's color and font color instead of the Panel's color and font color:
void __fastcall TForm1::Panel1MouseEnter(TObject *Sender)
{
this->Color = cl3DLight;
this->Font->Color = clMaroon;
}
Also, if I do the same as above but omit the keyword 'this', it still changes the Form's properties instead of the Panel's (see code below).
void __fastcall TForm1::Panel1MouseEnter(TObject *Sender)
{
Color = cl3DLight;
Font->Color = clMaroon;
}
How would I code this so it accesses the Panel's 'Color' and 'Font->Color' instead of the Form's? Thank you.
Note: The reason that I haven't just done it as: Panel1->Color = "cl3DLight"; is because I'm trying to find a way to do it for components created at run-time.
The Sender parameter represents the component that is generating the event. You can typecast that pointer to the proper type in order to access that component's properties.
If you know for sure that everything attached to the event is a TPanel, you can typecast it directly (as Remy pointed out in comments below):
void __fastcall TForm1::Panel1MouseEnter(TObject *Sender)
{
TPanel *panel = static_cast<TPanel *>(Sender);
panel->Color = cl3DLight;
panel->Font->Color = clMaroon;
}
If you're using the same event handler for different control types, you can test for the appropriate type instead:
void __fastcall TForm1::Panel1MouseEnter(TObject *Sender)
{
TPanel *panel = dynamic_cast<TPanel *>(Sender);
if (panel)
{
panel->Color = cl3DLight;
panel->Font->Color = clMaroon;
}
}
Related
I am playing around with Vala and GTK4.
FileChooserDialog is not working for me
using Gtk;
int main (string[] argv) {
// Create a new application
var app = new Gtk.Application ("com.example.GtkApplication",
GLib.ApplicationFlags.FLAGS_NONE);
app.activate.connect (() => {
// Create a new window
var window = new Gtk.ApplicationWindow (app);
window.title = "File chooser";
window.set_default_size (350, 70);
window.resizable = false;
// Create a new button
var file_choose_button = new Gtk.Button.with_label ("...");
file_choose_button.clicked.connect (() => {
var fileChooser = new FileChooserDialog(
"Select File",
window,
FileChooserAction.OPEN,
"Cancel",
ResponseType.CANCEL,
"Open",
ResponseType.ACCEPT,
null);
fileChooser.response.connect(()=> {
stdout.printf("File selectd!");
});
// WHAT TO DO IN ORDER TO SHOW FILE CHOOSER?
});
window.set_child (file_choose_button);
// Show
window.present ();
});
return app.run (argv);
}
I am missing some important piece of code, that will cause the FileChooserDialog to "appear".
In previous Versions of GTK there is "dialog.run" - which is missing in GTK4.
The C-Example on https://docs.gtk.org/gtk4/class.FileChooserDialog.html uses makro(?) "gtk_widget_show(xxx)" for which I was not able to find an representation in Vala.
Any help appreciated!
Best Regards
Emil
After some struggle the solution was found (and is pretty simple).
As stated in the Vala Documentaion Site - File Chooser Dialog
It inherits from couple of classes one of which is GTK.Window.
So it is as simple as calling the present() method.
Thus the missing command above is:
fileChooser.present();
One should not forget to use the close() method once file was selected or selection was canceled.
Important note:
"gtk_widget_show()" representation in Vala is GTK.Widget.show() BUT
I was not clever enough to find out how to prepare the parameter.
It expects pointer (GtkWidget*) and simply passing the "fileChooser" causes all kinds of compiler exceptions.
May be someone can throw more light on this (as I am using Vala to avoid the use of C - I am clearly not the expert in this area)
In a C++ Builder 6 test project, I try to understand the relation between the TWinControl classes of the VCL and Windows user objects, because I'm hunting a leak of user objects in my original application where I use some levels of nested frames, created periodically at runtime, that causes my application to crash after some days.
In the test project I observe a strange behaviour. When I add a dynamically created TFrame object to a panel, the count of user objects increases by 2. If I remove a frame by deletion, the user object count is decreased by 1. If I add it again, the increment is 1. If I add more than 1 frame, the increment is 2 after exceeding the last maximum value of frames. This is the code to reproduce this:
MainForm.cpp
#include <vcl.h>
#pragma hdrstop
#include "MainFrm.h"
#pragma resource "*.dfm"
TMainForm *MainForm;
int UserObjectCount() {
return GetGuiResources(GetCurrentProcess(), 1);
}
__fastcall TMainForm::TMainForm(TComponent* Owner)
: TForm(Owner)
{
}
void __fastcall TMainForm::AddButtonClick(TObject *Sender)
{
String msg = "add: "+IntToStr(UserObjectCount())+",";
(new TFrame(static_cast<TComponent*>(NULL)))->Parent = FramesPanel;
trace(msg+IntToStr(UserObjectCount()));
}
void __fastcall TMainForm::RemoveButtonClick(TObject *Sender)
{
if (!FramesPanel->ControlCount) return;
String msg = "rem: "+IntToStr(UserObjectCount())+",";
FramesPanel->Controls[0]->Free();
trace(msg+IntToStr(UserObjectCount()));
}
void TMainForm::trace(const String& msg)
{
TraceMemo->Lines->Add(msg);
}
It looks like a kind of caching. See the (grouped) excerpt of the trace (format action: before,after):
add: 28,30
rem: 30,29
add: 29,30
add: 30,32
rem: 32,31
rem: 31,30
add: 30,31
add: 31,32
add: 32,34
rem: 34,33
rem: 33,32
rem: 32,31
Another observation: If I use TPanel instead of TFrame, the behaviour is is trivial.
As to understand whether this is a Windows feature, I built another test application with Lazarus (Google didn't help). Here the user object count behaviour is unsurprising: increment and decrement compensate each other.
What is the explanation of this caching-like behaviour? How to get back to the initial count of user objects?
I'm sorry for pushing you back into the old times of BCB6.
I think I'm lacking in a fundamental understanding of dart, but basically what I want to do is something like this:
void main() {
new MyClass();
}
class MyClass {
MyClass() {
CanvasElement canvas = querySelector("#myCanvas");
CanvasRenderingContext2D context = canvas.context2D;
}
}
However, canvas is a null object by the time I try to get the context. How can I do this from within the class. Also, I don't want to do this:
void main() {
CanvasElement canvas = querySelector("#myCanvas");
new MyClass(canvas);
}
class MyClass {
CanvasElement canvas
MyClass(this.canvas) {
canvas = this.canvas;
CanvasRenderingContext2D context = canvas.context2D;
}
}
Because I need to be able to do this completely from within the class. Is this just not how dart works, or am I missing something?
Did you try your second example? It doesn't make a difference if you call querySelector from main() or from within a class.
Do you use Angular or Polymer?
Angular or Polymer components introduce shadowDOM. querySelector() doesn't cross shadowDOM boundaries and it therefore doesn't find elements inside an elements shadowDOM.
To query for elements inside a shadowDOM you query for the component and then you can continue the search.
querySelector("somecomponent").shadowRoot.querySelector("someothercomponent").shadowRoot.querySelector("#myCanvas");
You have to ensure that the DOM including all shadowDOMs is fully built before you can query them.
If you run your code from within a component pub your code into the onShadowRoot method (see NgComponent ready event for more details)
Say I have an object
var my_obj = new Object();
my_obj['key'] = value;
Is there a way to add an event listener to the value, like
my_obj['key'].addEventListener(Blah Blah);
I have a long(ish) list of buttons on the timeline (the layout is so different from section to section that just makes more sense to do on the timeline rather than trying to build the layouts via actionscript).
button1 = plays "frame label 1"
button2 = plays "frame label 2"
and so on....so I was just thinking of storing everything in an array
obj["button1"] = "framelabel1"
arr.push(obj);
Then I could just have one event handler for all of the buttons and use target to get the frame label value...
Yes, you can do exactly what you're asking in the exact way you've mentioned, here's an example:
var value:Sprite = new Sprite();
var my_obj = new Object();
my_obj['key'] = value;
So calling:
my_obj['key'].addEventListener(Event.ENTER_FRAME, _onEnterFrameHandler);
is exactly the same as calling:
value.addEventListener(Event.ENTER_FRAME, _onEnterFrameHandler);
If the value is an IEventDispatcher or extends EventDispatcher you can add a listener to it.
The question is rather obscure to me. My guess is that you need something triggered every time a value is set. If this is the case, then you have to create a custom class, and declare a getter-setter property there.
For instance:
package
{
import flash.display.Sprite;
public class TestAccessor extends Sprite
{
private var someVarValue:uint = 0;
public function TestAccessor()
{
super();
}
public function get someVar():uint
{
return someVarValue;
}
public function set someVar(value:uint):*
{
someVarValue = value;
// this is the place where someVar is set.
// do whatever else you like here,
// you may choose to dispatch an event from here if you need.
}
}
}
Back in AS1-AS2 era we had watch() and addProperty() for that purpose, but these times are long since gone. For good. :)
How can I get the selected items in TListBox and add the items in the second TListBox, Im using Borland C++ Builder 6.
As David said in his answer, you need to use the Selected property.
Here is a simple function I have used in several projects in the past.
void __fastcall TSelectForm::CopySelectedList(TListBox *SrcLB, TListBox *DestLB, bool ClearDest)
{
DestLB->Items->BeginUpdate();
if (ClearDest) DestLB->Clear();
// copy selected items from source listbox
for (int Index = 0; Index < SrcLB->Count; ++Index)
{
if (SrcLB->Selected[Index])
{
DestLB->Items->Add(SrcLB->Items->Strings[Index]);
} // end if
} // end for
DestLB->Items->EndUpdate();
} // end CopySelectedList
You need to iterate over the Selected[] property. if Selected[i]==true then Items[i] is selected.