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

Posted on 2003-03-18
Medium Priority
Last Modified: 2010-04-01

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.
Question by:Joeriw
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4

Expert Comment

ID: 8158426
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!

Author Comment

ID: 8158457
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

Author Comment

ID: 8158643
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.

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!


Author Comment

ID: 8159782
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
LVL 12

Accepted Solution

Salte earned 200 total points
ID: 8160760
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.



Author Comment

ID: 8160905
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)

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
Suggested Courses

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question