Skip to main content
Topic: Problem with preference_page_instance (Read 3762 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

Problem with preference_page_instance

Hi,

I'm trying to upgrade my (very old) input plugin to the new SDK. It was originally written against 0.8.3.
It compiled cleanly, and playback is working. However the configuration page did not support apply/reset, so I wanted to upgrade it.

I updated my v2 prefpage to v3, derived a class from preference_page_instance.
However, my preference page is a very very simple non-WTL/ATL/MFC dialog, so the WTL helpers are not appropriate (they don't even compile since I don't have WTL installed).

This leaves me in a situation where my plugin does not compile, because preference_page_instance does not implement service_release() or service_add_ref(). This seems to be contrary to the SDK readme, which says that those are defined by the services and should NOT be overridden by implementations.

Is it safe for me to implement those 2 methods as no-ops? Do I have to use them alongside or instead of using a destructor? Or am I _required_ to switch to using WTL for my preference page?

Problem with preference_page_instance

Reply #1
If you check the preferences_page_impl template in ATLHelpers\misc.h, you'll see that you need to use service_impl_t and another helper template to instantiate your class. In fact, both of those classes look like they're ATL-free, so I don't know why they're in the ATL helpers project and not SDK\preferences_page.h

Problem with preference_page_instance

Reply #2
If you check the preferences_page_impl template in ATLHelpers\misc.h, you'll see that you need to use service_impl_t and another helper template to instantiate your class. In fact, both of those classes look like they're ATL-free, so I don't know why they're in the ATL helpers project and not SDK\preferences_page.h


Actually in the current SDK (2010-10-02), preference_page_impl uses window_service_impl_t, which is specific to WTL/ATL. Like preference_page_instance_impl, it expects to work with a TDialog.
However, you did point me to service_impl_t so I used that for the implementation of preference_page_v3::instantiate() instead of using plain new (and implementing my own service_xxx() methods), and that seems to work. Looking now, the readme does say that service classes are supposed to be instantiated that way - this was the first time I was doing any instantiating (as opposed to just providing a factory for foobar to use).

Thanks.



Problem with preference_page_instance

Reply #3
An important point to remember is that particular factory also caught errors with calling the Create function (which called CreateWindow or CreateDialog or whatever) using the WIN32_OP macro, at least I think it does. Hmm...

Problem with preference_page_instance

Reply #4
An important point to remember is that particular factory also caught errors with calling the Create function (which called CreateWindow or CreateDialog or whatever) using the WIN32_OP macro, at least I think it does. Hmm...


Yeah, there was some mention of avoiding problems. However, the only available "fixed" code seems to be WTL/ATL specific, so is of no use for me.
Anyway, my page is currently working, but since all it allows you to configure is whether or not to loop the files (and how many times to loop them), and whether or not to apply a fade-out, perhaps I should simply see about moving that into the advanced prefs and avoid the whole issue of handling a dialog (including the crap you need to pull to have the dialog handling in a class instance because dialogproc can't get a this pointer passed to it).

Problem with preference_page_instance

Reply #5
Yes, DialogProc can receive a class pointer. You just need to use DWL_USER with SetWindowLong/GetWindowLong, or DWLP_USER with SetWindowLongPtr/GetWindowLongPtr. (Although the latter is only really necessary if you're compiling 64-bit code, which you aren't.)

Problem with preference_page_instance

Reply #6
Yes, DialogProc can receive a class pointer. You just need to use DWL_USER with SetWindowLong/GetWindowLong, or DWLP_USER with SetWindowLongPtr/GetWindowLongPtr. (Although the latter is only really necessary if you're compiling 64-bit code, which you aren't.)


I'll give that a try (beats keeping a map of hwnd-to-classptr); either way it does not allow me to handle WM_INITDIALOG in the dialogproc (has already been sent by the time CreateDialog has returned). Thanks for all the help in any case.

Problem with preference_page_instance

Reply #7
That's strange, it should be passing the WM_INITDIALOG message to your dialogproc proper. Maybe you should set a breakpoint in the dialogproc and see if it gets called at all?

Problem with preference_page_instance

Reply #8
If you're having trouble getting a pointer to your class instance while handling WM_INITDIALOG, pass it through CreateDialogParam() parameter and do SetWindowLongPtr() inside your WM_INITDIALOG handler.

Problem with preference_page_instance

Reply #9
That's strange, it should be passing the WM_INITDIALOG message to your dialogproc proper. Maybe you should set a breakpoint in the dialogproc and see if it gets called at all?


The problem was that by the time I got the HWND back from CreateDialog, WM_INITDIALOG had already been sent, so I could not yet use the class member functions to handle it, because I could not associate the hwnd with the class instance in time.

If you're having trouble getting a pointer to your class instance while handling WM_INITDIALOG, pass it through CreateDialogParam() parameter and do SetWindowLongPtr() inside your WM_INITDIALOG handler.


That looks like it would do the trick. I'll give that a try but I'll still look at moving the two settings to advanced prefs and avoid the hassle altogether.

Problem with preference_page_instance

Reply #10
Silly me, I had assumed you would be assigning the pointer to your DWL_USER in the WM_INITDIALOG function. You'd pass the class pointer with CreateDialogParam, then receive it in WM_INITDIALOG as the lParam to your DialogProc. Your static DialogProc would either receive the class pointer that way on WM_INITDIALOG and set it to its DWL_USER, or retrieve it from there on all other window message types, and branch off to your class member dialog process function if the result of either of those steps is a non-NULL pointer.

Problem with preference_page_instance

Reply #11
Things are working cleanly using the suggestions you made. I'm keeping the preference page; I looked at using advanced prefs, but the "integer" entry is actually accepts natural numbers only (i.e. it does not support negative values), and one of my two variables needs to allow "-1" as a value.
Thanks for the help.

So now my only remaining issue is the tagging troubles (reported separately).

 
SimplePortal 1.0.0 RC1 © 2008-2019