What exactly is an event table and what does it do? I am asking regarding wxWidgets but maybe its a general GUI programming concept, so please correct me on that.
To keep it simple, the evend table tells which function to call when which event occurrs.
However, it is an old way of mapping events to functions.
It is no longer recommanded because isn't very flexible, and use macro tricks to do its job.
Macros themselves are generally not very recommanded in C++.
Unless you must stick to C++03, you should no longer use event tables.
Instead, you should use the bind method for New WXWidgets projects in C++11 or later.
Bind is more flexible, and don't use macro.
You will find this recommandation in the WXWidgets tutorials, too.
You must still be able to read and understand old event tables, though, because many samples haven't been updated for ages.
An event table tells wxWidgets to map events to member functions. It should be defined in a .cpp file.
wxBEGIN_EVENT_TABLE()
is an example of a macro
In addition to the other answers, I'd like to say that if you're starting learning wxWidgets, you should know that event tables are a legacy way of handling events and that using Bind() is the preferred way of doing it in the new code.
In particular, Bind() is much less "magic", and doesn't use any macros.
Related
Imagine a project with the development stretched over 10+ years timespan. Some parts are in C, some are in C++ and all of the code uses global functions and global variables. The architecture was designed inherently single threaded and kept growing that way. But now we consider utilizing many-core architectures.
Now one idea being evaluated is to refactor a part of the code into a library, to make it possible to create more than one instance, so that they can run in separate threads and don’t interfere with each other.
The proposal that gains the most traction at this point is to wrap all the library files into namespaces with macro defines, like:
namespace VARIANT {
// all the code
}
Then define the VARIANT in a header or on project level. This will make it possible to have different contexts within different namespaces. And the selling point is that this approach will require minimal code change and has low risk of introducing any regression.
But if at some point we need to make the behavior of Variant1 different from Variant2, things will get tricky, since there’s no way to compare the value of a macro define with a string in a preprocessor macro.
Is there a more elegant way to achieve this?
Another variant might be spotting all global variables and making them thread_local. Requires either C++11 or at least compiler extensions providing the same (__thread using older GCC).
If I read this question right, you even don't need to convert your C files into C++ files (which your approach requires as C does not support namespaces...), but you need C11 for.
Refactoring an old project and make it multithreading is not so simple. First of all you have mixture of C and C++ codes and you cannot blindly follow C++ approach here. Instead of namespace you need to thing on the below areas:-
Find out all the code blocks, container like list, large array of objects etc which need synchronization.
Find out interdependency of threads and how will you control them. For example one thread will generate a report and insert into a table and second one need that information to generate its final report, now you need to find out these kind of dependency among the threads in your code base and need to find out their control mechanism.
Old style of multithreading in C++ was very tricky hence you need to migrate your code to C++11 where implementation of multithreading is much easier.
As you said that in your current project there are lots of global variable, you need to think properly how you are going to share these variables amongst different threads and how will you synchronize access of these variables.
These are some hints you need to consider lots of areas in advance before starting refactoring else all your efforts end in smoke.
GOOD LUCK for your plan.
Just do it in steps, testing each time:
1) typedef a struct with all the globals in it. malloc one, and edit the existing code to reference it. Test - should work exactly the same as with the globals.
2) Create one thread to run one instance of the code. Test - should work exactly the same as with the globals.
3) Try multiple threads.
One step at a time...
Please try very hard to not attempt any bodges!
The question is in the title: How can I have the callback for SetWinEventHook have some context information? Usually functions that take callbacks also take a context parameter they pass on to the callbacks, but not this one.
Using a global (including thread_local) variable as suggested in SetWinEventHook with custom data for example is almost certainly unacceptable.
There may be more than one caller to the utility function that sets the WinEvent hook to do something so global is out. thread_local may work, but it also may not. What if the callback calls the same utility function and sets yet another hook? They will both get called next time I pump messages. Using thread_local requires me to define a contract that forbids a single thread to set more than one WinEvent hook through me, and requires my callers to abide by it. That's a pretty arbitrary and artificial limitation and I prefer not to set it.
I'm reimplementing in C++ a little PoC I had in C#. There I could simple use capturing lambdas and they would convert to function pointers that I can pass via P/Invoke to SetWinEventHook. C++ unfortunately doesn't have that feature (probably because it requires allocating WX memory and dynamically generating a little code, which some platforms don't allow), but perhaps there is a platform-specific way to do this?
I seem to remember that ATL did something like that in the past, and I guess I can probably implement something like this too, but maybe there's a better way? If not, perhaps somebody has already written something like that?
(Another valid solution would be a clever-enough data structure and algorithm to solve the reentrancy problem.)
About the last year I did Java(Android)-programming, and did C# the Year before that. About a month now I'm learning C++, and since I got over friends, inheritance and stuff, I got a few questions, since I haven't been working with it up until now:
Is there a way for a class to define friends later on, because they need to exchange information or something. e.g. is there a way to define a 'random' friend later on? what do you need for that? The function's name or the address of the class?
Or is there generally a way to change the code from the program itself, so that it won't be necessary to recompile? e.g. creating new functions, classes or so?
I'd be very happy about any answer about that.
What you want to do is not possible with C++. If you need that sort of dynamically changing the program, you are better advised using a more dynamic higher-level language like Lisp.
friends can only be added to a class by modifying its source code. This is a feature, not a bug.
There are two ways to extend functionality like that.
Use dynamically loaded modules with the extended functionality. These modules supply a specific interface, and can be compiled separately from the main program.
Add support for scripting - allow users to add write scripts, and run them from inside your program.
The first solution is easier, depending on how much control you want to give those scripts.
I have just started learning wxWidgets, version 3.0, with C++. I have noted, that event handling in wxWidgets is done by Event tables. But one tutorial also mentioned Connect() - actually it just said : " this tutorial will be using event tables, not Connect() " .
I would like to know, what is the philosophy behind Event tables and behind Connect() ? What is the difference, when is one more suitable than the other... Thank you.
First, don't use Connect() which was superseded by Bind() which is better in every way.
Second, both static (using event tables) and dynamic (using Bind()) methods of handling events work and you can use whichever you prefer. Personally, I recommend using Bind() because
It is much more flexible: can be used to connect the event on one object to any other object or even a free function or, in C++11, a lambda.
It is safer and catches most common errors such as using wrong event handler signature at compile time.
It is "dynamic", i.e. you can connect and disconnect the handler at any time.
The main advantages of the event tables are that
They are slightly shorter, especially in pre 3.0 versions.
They are much more common in documentation, examples, tutorials, ... just because they had a 15 year head start on Bind().
However they are clumsier to use because they require subclassing (deriving a new class from) an object in order to handle non-command events in it and they don't detect all errors at compile-time allowing you to write code that compiles fine but crashes at run-time.
I've been developing for some time. And these beasts appear from time to time in MFC, wxWidgets code, and yet I can't find any info on what they do exactly.
As I understand, they appeared before dynamic_cast was integrated into core C++. And the purpose, is to allow for object creation on the fly, and runtime dynamic casts.
But this is where all the information I found, ends.
I've run into some sample code that uses DECLARE_DYNAMIC_CLASS and IMPLEMENT_DYNAMIC_CLASS within a DLL, and that is used for exported classes. And this structure confuses me.
Why is it done this way? Is that a plugin based approach, where you call LoadLibrary and then call the CreateDynamicClass to get a pointer which can be casted to the needed type?
Does the DECLARE/IMPLEMENT_DYNAMIC work over DLL boundaries? Since even class is not so safe to DLLEXPORT, and here we have a custom RTTI table in addition to existing problems.
Is it possible to derive my class from a DYNAMIC_CLASS from another DLL, how would it work?
Can anyone please explain me what these things are for, or where I can find more than a two sentences on a topic?
This stuff appends addional type information to your class, which allows to RTTI in runtime-independent manner, possibility of having factories to create your classes and many other things. You can find similar approach at COM, QMetaObject, etc
Have you looked at the definitions of DECLARE/IMPLEMENT_DYNAMIC?
In the MS world, all uppercase usually denotes a macro, so you can just look up the definition and try to work out what it's doing from there. If you're in Visual Studio, there's a key you can hit to jump to the definition - see what it says, and look that up and try to work from there.