Measurement Studio for VC++

cancel
Showing results for 
Search instead for 
Did you mean: 

Windowless controls problem...

Hello Michal,

Yes you are correct in your summarizations of the prior statements.  In answer to your questions about example code, I believe that the link in Jonathan's last post (MFCClientSite) has a decent example.  I also found this example that should give you an additional resource.  Unfortunately we don't have much of anything along those lines laying around here.  If you do have some specific questions we can definitely take a look at them, but it may also be useful to check into some C++ forums also since there might be individuals there who have had more experience on this topic. Happy coding.

John B.
Applications Engineer
National Instruments
0 Kudos
Message 11 of 12
(4,087 Views)
Hello

I've solved the problem. Yesterday I saw first windowless Knob in my own application :-). Now, I have some notes (perhaps that will come in handy for someone else trying to get windowless controls), and a small request for help, too:
1) It is true that NI Controls can be made windowless in C++/MFC environment. One has to have good implementation of ActiveX container (by the way, I tried these mentioned above even before I started asking questions here. With no good result, takes hours to actually make them compile, and all I was able to get was assertion failures), I took mine from Mozilla Firefox code, combined with some patches from their bug tracking system and finally modified a bit, because original version failed to work with NI controls.
2) It is not true that NI Controls detect windowless container, and automatically run in the windowless mode. At least, not with Visual C++ 2003, not 8.1.11.337 version, not here. I've tested my container with snippet of code provided by Jonathan, and it had required interface, and of course CanWindowlessActivate function returned true. But NI controls instantiated within this container failed to call CanWindowlessActivate, they were content with caling CanInPlaceActivate and in place activation, instead of windowless activation. You can see this for yourself: just take ActiveX Control Test Container (ships with Visual Studio 2003, other versions too), insert any NI Control and use either Spy++ (Visual Studio tool, too) or Container menu "Info" option to check out. NI controls activate in the "windowed" state, period. At least on this side of Atlantic Ocean 😉
3) So how does one _force_ NI controls to actually create themselves in "windowless" mode? Easy. As I wrote previously, one has to have "windowless template" for the control. I do it by instantiating ordinary, windowed control, setting it up and allowing it to process all initial window messages (this one is very important, failing to do so makes control to produce bad template!). Then, control state has to be serialized (I use Ole streams for that). Subsequent controls have to be created from this very serialized state. Guess what? They call CanWindowlessActivate and then setup in windowless mode, just fine! If you don't believe me, give it a try under said Control Test Container. Create control, it will instantiate as windowed. Call method SetWindowless (PROP PUT), with argument set to true. Nothing happens. Serialize everything to a file. Delete control instance. Create new, but from file just written and...voila! You have your windowless control!
4) There are some little quirks and fixes here and there that has to be done for this all to work. For example, routing WM_SIZE to control makes it fail with zero pointer dereference. Oh well...my controls are created using their "final" size, so I just don't route WM_SIZE anymore.
5) No painting issues so far. Guess I have good control container/site 😄

Now, I'd really appreciate if someone could help me a bit with this: I have my windowless control but, alas, it is not wrapped into that nice NI::CNiKnob (or whatever) class. That's sad, for although I used to do bare-COM interaction with NI controls back then, I have written much code relying on this excellent NI::CNiSomething interfaces, and really loved them. Is there a way for a control to be created using raw COM calls, like CoCreateInstance (and so on), which is exactly what my container does, and then somehow wrap IUnknown into CNiSomething? Or do I have to do via CNiSomething ctor, and I should rather concentrate my efforts onto making it use my control site (simply, the other way round). Any help will be appreciated....

Best regards
Michal


0 Kudos
Message 12 of 12
(4,048 Views)