I am trying to color the button by using CColorbutton class function setcolor. It is working fine when I have declared the member variable of button but it is not working when I directly get the handle by GetDlgItem(IDC_BUTTON1). Can anyone tell me the solution of this?
CColorButton* pWnd = (CColorButton*)GetDlgItem(id+i);
pWnd->SetColor(RGB(0,0,0),RGB(200, 153, 204));
First of all: Without declaring a variable for the button control you will not get it to run!
Why? A window Variable and using DDX-Control or using CWNd::SubclassWindow is the way, subclassing works in the MFC. Without subclassing the messages are not handled by the code that is used in CCOlorButton.
Yes you can use GetDlgItem and my do a hard cast to CColorButton, but this is extremely dangerous! Why? The window object you get is just a temporary CWnd object with no additional member variables. If you call a specific member function of a CColorButton, that uses additional data members you may destroy your memory/heap/stack content.
With a MFC control class you always need the specific object somewhere in memory to suavely cast a pointer that GetDlgItem returns!
If you have a member function you don't need a cast. If (for any other reason) you need to cast a CWnd pointer, it is wise to use STATIC_DOWNCAST/DYNAMIC_DOWNCAST to get ASSERTs when something is wrong.
If you do not declare and properly initialize a CColorButton variable then there is no CColorButton object in your program. So you are calling something that does not exist. You asked for the solution of this, but you already know the solution!
Related
I found multiple questions regarding custom QEvents. So since Qt 4 we have to derive from QEvent and register our custom type. There are some samples around.
What I want is a QWheelEvent with custom data in it. So the event should be usable everywhere as a "normal" QWheelEvent but if I want to I can check for my CustomWheelEvent type and retrieve the data from it.
The problem is that I don't know how to register the type because the constructor of the QWheelEvent does not offer the possibility to set the event type.
Looking at the internals of QEvent I could simply set the protected member Type t to an event type returned by registerEventType(). Does this have side-effects?
If I simply derive from QWheelEvent I can also use dynamic_cast to find out if it is my own event carrying my custom data. A simple static cast after a check for the type should be better though.
Any thoughts on this?
Edit: I have tried the approach with dynamic_casts but the cast seems to fail. This is possible if Qt deep-copies the event internally, so that a new QWheelEvent is created and passed through the event system instead of my CustomWheelEvent. This way my own data (defined in CustomWheelEvent) is stripped off the object and only the base class (QWheelEvent) is handled. I originally thought that the pointer is used as it is, so that I can rely on the dynamic_cast. More information on this is appreciated!
Read this:
Qt: Defining a custom event type
I think that you do want to register the event and that it will return a new unused type (number). In an example there, the static object sets the value to QEvent::None. The primary problem I see with the solution there is that it is not thread safe, so, be sure to make this thread safe somehow (like maybe call the static type method before things start so that they are initialized before it could be used in a multi-threaded way).
I extended the class wxFileSystemHandler to handle special protocols I use in my application. My implementation of wxFileSystemHandler::CanOpen() is called, recognizes the protocol and returns TRUE. But my implementation of wxFileSystemHandler::OpenFile() never gets called. I inspected the wxWidgets code and saw that the CanOpen() member function is called by the pointer that I registered. But when a call to OpenFile() is made they pass the pointer to a wxFileSystem::MakeLocal() member function that tries to get another pointer inside a hash map that, obviously, is not my instance.
Someone got a problem like this before?
Not sure what exactly are you doing, i.e. when do you expect your handler to be called, but in any case MakeLocal() is supposed to create a new instance of the same class if you mark the object as being dynamically creatable using wxRTTI macros and use the object as given otherwise. So if you really need the same object to be reused, you probably need to use wxDECLARE_ABSTRACT_CLASS() in its class. But OTOH why is it a problem to make a new instance?
I wrote this simple const class method:
void CTest::MSGTest() const
{
MessageBox(_T("This is a simple test"));
}
This method has an error:
The object has type qualifiers that are not compatible with the member function CTest::MessageBoxW
I know this is because i use the const. A method can be a const method if no member variables are modify while the execution. I would like to know which variables the MessageBox modify and how the modification manifests.
I think it is the handler m_hWnd, but I don't know.
The problem isn't that neither your function nor MessageBox modify any members variables - they don't and that's easy to see.
The problem is that MessageBox is not marked as const and so you have a const member function (yours) calling non const one (MessageBox). This isn't allowed and that's the issue.
So why isn't it marked const? I doubt you will ever get a definitive answer to that question if one reason really exists.
Personally, I suspect it's a combination of factors that caused it to not be const originally and now it is what it is.
One potential reason is that a lot of internal MFC bits and pieces involve the manipulation and adjustment of maps - for example maps which associate windows HWND objects to MFC CWnd objects.
It's possible that they had to relax the use of const to account for calls to non const functions deep down the call chain in places that users never see.
So why not use mutable then or maybe even const_cast? Remember that MFC has been around for a long time and when it was designed the Microsoft compiler might not have support for some of the more exotic features of C++ at the time.
In my opinion, if CTest is derived from CWnd (explicitly or not) - showing a dialog box on this CWnd object means changing the state of window/control. Assume CTest is derived from a CDialog, and pressing some button causes this function (CTest::MsgTest) to be called. It effectively means that state of the dialog-box has changed (from user's perspective). It is not important if modal or modeless dialog is shown - the state has changed, hence the method shouldn't be const.
I see several code examples showing variables and object creations inside of the InitInstance() function of an MFC appObject (i.e. theApp). I thought anything created inside a function dies when the function exits. And the InitInstance function does appear to exit prior to the program exiting, just after showing the windows.
What am I missing? How does this work?
Yes, you are correct: objects created at function scope with automatic storage duration will be automatically destroyed when the function exists.
There are two possible explanations for what you're seeing (it's hard to narrow it down any more than that since you didn't include any example code with your question):
The objects are actually being created using the new keyword, which means that they have dynamic storage duration and are not automatically destroyed. Instead, they must be manually destroyed using the delete keyword. In addition to seeing new, a dead giveaway of this style is the use of pointers—new returns a pointer to the new object, so you'll see * all over the place.
The object doesn't actually need to exist any longer than the function in which it is declared. It might be temporarily created just so that some of its member functions can be called. The effects of these member functions are global or have effects beyond the class object itself. This is rather common in MFC, since most of the classes are wrappers around the Win32 API.
For example, the CWnd class is just an object-oriented wrapper around a Win32 window, represented by an HWND (or handle to a window). You can create a CWnd object, use it to create and manipulate a Windows window (HWND), and then allow it to be destroyed without affecting the underlying Windows window. The "Remarks" section of the CWnd documentation talks a bit about this confusing behavior:
A CWnd object is distinct from a Windows window, but the two are tightly linked. A CWnd object is created or destroyed by the CWnd constructor and destructor. The Windows window, on the other hand, is a data structure internal to Windows that is created by a Create member function and destroyed by the CWnd virtual destructor. The DestroyWindow function destroys the Windows window without destroying the object.
You did mention the ubiquitous theApp object in your question, though. That one is a little different—it's actually a global object because it is not declared inside of any function's scope. It is automatically constructed when the program begins executing, and automatically destroyed when the program ends.
So, I'm using the FMOD api and it really is a C api.
Not that that's bad or anything. Its just it doesn't interface well with C++ code.
For example, using
FMOD_Channel_SetCallback( channel, callbackFunc ) ;
It wants a C-style function for callbackFunc, but I want to pass it a member function of a class.
I ended up using the Win32 trick for this, making the member function static. It then works as a callback into FMOD.
Now I have to hack apart my code to make some of the members static, just to account for FMOD's C-ness.
I wonder if its possible in FMOD or if there's a work around to link up the callback to a specific C++ object's instance member function (not a static function). It would be much smoother.
You cannot directly pass a member function. A member function has the implicit parameter this and C functions don't.
You'll need to create a trampoline (not sure the signature of the callback, so just doing something random here).
extern "C" int fmod_callback( ... args ...)
{
return object->member();
}
One issue is where does that object pointer come from. Hopefully, fmod gives you a generic context value that will be provided to you when your callback is made (you can then pass in the object pointer).
If not, you'll just need to make it a global to access it.
I guess it supposed to work like this:
You can assign some user data to channel by calling FMOD_Channel_SetUserData. This user data should be a pointer to your C++ object that handles events.
Then you should write C-style callback that extracts that object by calling FMOD_Channel_GetUserData and then calls your C++ instance method on that object.
There is a non-portable, and pretty hackish solution that has the advantage of at least being thread-safe, which the "trampoline" methods are not.
You can generate the actual function machine code on the fly. The basic idea is that you have a template for your call-back function that takes an object pointer and a member-function pointer and gives you a block of heap memory that you can pass to the library as a C call-back function, that will, when called, turn around and call the member function on that object.
It's messy, and you'll have to provide an implementation for any new platform (any time the calling convention changes), but it works, is thread-safe. (Of course you'll also have to watch out for DEP). The other thread-safe solution is to resort to thread-local storage (assuming that you know the call-back will happen on the same thread as the call you made).
See http://www.codeproject.com/KB/cpp/GenericThunks.aspx for an example of how you could go about generating thunks.
Using only a function pointer (and no additional separate object pointer) for a C callback is a broken design, in my humble opinion.
If the function were, instead, FMOD_Channel_SetCallback(channel, callbackFunc, callbackObj), then your static method just takes an instance of the object, then calls callbackObj->func() (which obviously can be non-static).
you need to use a trampoline and store the pointer to the object you want to get the member function called on in a global or static variable, i.e.
Object *x;
void callback_trampoline() { x->foobar(); }
...
FMOD_Channel_SetCallback(CHANNEL, callback_trampoline);