How do i make 1 application for both win98 and winxp; with win98 using CButton for my buttons and winxp using CXPStyleButtonS


i got the following problem :

i created a CFormView based app, with most of my buttons declared as CXPStyleButtonST buttons.
Problem is, these buttons look very dumb in windows 98. I prefer not to make 2 different versions, but instead let the program determine the OS (i got a function for that) and then either use CButton or CXPStyleButtonST. Sounds simple, but it surely isn't. I thought to use this:

#ifdef _WINXP
     CXPStyleButtonST Button1;
     CXPStyleButtonST Button2;
        CButton Button1;
     CButton Button2;

but the problem is where can i call my function (and let its outcome do either #define _WINXP or #define _WIN98) before it checks this... ??
Anyone got the answer?
I for now only got 50 points for the answer but i will consider a bonus when i got more points.
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Your #ifdef things will be used at compile time only, and I can't see how you could call a function at that time. BUT what you sure can do is ask the compiler (whichever you use) to define constants depending on the OS (actually, it probably does it by default). Check your compiler's manual for this!
JoeriwAuthor Commented:
i use visual c++ 6.0
umm where is the compilers manual here? all i use is msdn.
By the way, im just busy with building this solution, and it compiles.. will let you know in a bit
JoeriwAuthor Commented:
damn, i know understand every word you said :)

#include "simexhelper.h"

#define _OS_WIN2003 6
#define _OS_WINXP 5
#define _OS_WIN2000 4
#define _OS_WINNT 3
#define _OS_WIN98 2
#define _OS_WIN95 1
#define _OS_WIN31 0
#define _OS_WINUNK -1

#ifndef _OSVERSION
static int _OSVERSION = CSimexhelper::GetWindowsVersion();

#define _WINXPMODE //this is the win xp version
#define _WIN98MODE    

this indeed can't work
as it will probably compile it to:

#include "simexhelper.h"
static int _OSVERSION = CSimexhelper::GetWindowsVersion();

 with _WIN98MODE defined. :(

Does someone know the compiler options then? Can't see them anywhere.

Cloud Class® Course: MCSA MCSE Windows Server 2012

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

JoeriwAuthor Commented:
found a way to get the desired result.

i used my helper function in the initialization of my document class,
so its BOOL xpmode would reflect the OS thats running.

then for every view i created CXPStyleButtonST 's and used:

void CIntroView::OnInitialUpdate()
     CMasterDoc* pDoc = (CMasterDoc*) GetDocument();
//sets icons (works in both w98 and winxp)
     if (pDoc->xpmode)
     { //create regular look in win98
works for me. if anyone knows how to check os on compile time please tell, otherwise the points will go to linzer
Seems like your problem is this:

you know at run time what OS you get.

The #if _WINXP thing is a compile time thing and doesn't really work well with the run time stuff.

So, you need to make up your mind if you want it to be different compile time versions or if you want it to have the same compile time versions and you do the test at run time as you indicated.

If you want to do the test at run time it is:

Important that you compile it under WinXP so that you have full access to both the Win98 stuff and the WinXP stuff.

When the program starts up you can test if you run WinXP or Win98 and set a bool variable.

bool WinXP = false;

at initialization you run your test and set it to true if you run on WinXP. (default value is false).

Then, obviously, if you want different buttons in the two cases you must do so by using references or pointers.

Instead of:

CXPStyleButtonST button;

you need something that can both be CXPStyleButtonST as well as plain old CButton.

I believe these two classes have a common baseclass, perhaps even CXPStyleButtonST is derived from CButton or CButton is derived from CXPStyleButtonST?

In any case, identify the baseclass that is common to both, This is either one of the two buttons classes or CControl or something.

Then declare something like this:

baseclass * button;

Now, when you create the button you do:

baseclass = WinXP ? new CXPStyleButtonST(....) : new CButton(...);

One problem is if you need to call a function func() which is defined in both CBUtton and in CXPStyleButtonST but not in CControl, then you can do the following:

If the member function is something like this:

int CButton::func(int x); // for CButton


int CXPStyleButtonST::xfunc(const char * s, int x);

This just show that the function name may be different and the parameters may differ but conceptually these two functions do the same thing to the button, so if the button is of type CBUtton you would want to call func with some arguments and you would call CXPStyleButtonST::xfunc with some possibly other arguments.

Then you can define a function like this:

int my_func(const char * s, int x, int y)
   if (WinXP)
      return dynamic_cast<CXPStyleButtonST *>(button)
               -> xfunc(s,x);
      return dynamic_cast<CButton *>(button)
               -> func(y);

Now, if you have several of these buttons you are probably better off putting all this in a class:

class MyButton : public baseclass {
    typedef CXStyleButtonST XPbutton_t;
    typedef CButton button_t;

    baseclass * button;

    static bool WinXP;

    XPbutton_t * XPbtn() const
    { return WinXP ? dynamic_cast<XPbutton_t>(button) : 0; }

    button_t * btn() const
    { return WinXP ? 0 : dynamic_cast<button_t>(button); }

    void create(.......);
    int func(const char * s, int x, int y);
    static void init(); // set WinXP variable.

void MyButton::create(....)
  button = WinXP ? new XPbutton_t(...) : new button_t(...);

int MyButton::func(const char * s, int x, int y)
   if (WinXP)
      XPbtn() -> xfunc(s,x);
    return btn() -> func(y);

Note that the class MyButton is derived form the common baseclass itself so you can override any virtual functions that you want and simply forward them to your button member.

int MyButton::some_func(const char * s)
   return button -> some_func(s);

Hope this is of help.



Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
JoeriwAuthor Commented:
Waw! explains all i would ever need for this case.
Thanks a lot for this!

If you can add a decent comment to this question

i can donate you a nice & well deserved 200 pts for your help (sorry i'm out of pts so can't give more)
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.