CProperty Sheet with Vertical Tabs 
Author Message
 CProperty Sheet with Vertical Tabs

I've successfully included a CPropertySheet on a FormView in my application,
but I want to have tabs on the right side of the property sheet instead of
the top.  I can use GetTabControl() on the property sheet and modify the
style.  This works fine if I set it to display the tabs on the bottom, and
it almost works for tabs on the right except the tab text disappears.  I've
tried resetting the text using the tab control SetItem() call but no text is
displayed.  I can easily do this with just a plain CTabCtrl, so why doesn't
it work for the Property Sheet?  Any ideas?  This is one topic I haven't
been able to find much written about.  Any help is greatly appreciated!

Thanks,

--------------------------------------------------------------------------

  [     \/     ]    University of Michigan
   | Michigan |     Space Physics Research Laboratory
   |  |\  /|  |     1207 Space Research Bldg.
  [____]\/[____]    2455 Hayward St.               Phone:  734-763-5373
                    Ann Arbor MI  48109-2143       Fax:    734-763-5567
--------------------------------------------------------------------------



Sat, 25 May 2002 03:00:00 GMT  
 CProperty Sheet with Vertical Tabs
Hi, Ryan!

I hadn't known this until you brought it up, but that's only because I've
never actually  used the TCS_VERTICAL|TCS_BOTTOM style before. Frankly,
despite the docs saying that you can change this style dynamically -- I
could not get it to work even at the CTabCtrl in a dialog box case --
nevermind in a CPropertySheet. Anyway, after much headscratching I came up
with a solution (or rather an idea for a solution), but it is a nightmarish
thing. It goes like this...

In your CProperySheet constructor do this...

CSheet::CSheet()
{
    m_psh.dwFlags |= PSH_USECALLBACK;
    m_psh.pfnCallback = &SheetCallBack;
    AddPage(&m_p1);
    AddPage(&m_p2);

Quote:
}

Then add the static function "SheetCallBack" (you can name it whatever you
want) to your CPropertySheet class declaration...

 static int CALLBACK SheetCallBack(HWND, UINT, LPARAM);

and then implement it like (something like) this...

#pragma pack(push, 1)

typedef struct

    WORD   dlgVer;
    WORD   signature;
    DWORD  helpID;
    DWORD  exStyle;
    DWORD  style;
    WORD   cDlgItems;
    short  x;
    short  y;
    short  cx;
    short  cy;

Quote:
} DLGTEMPLATEEX;

#pragma pack(pop)

int CALLBACK CSheet::SheetCallBack(HWND hWnd, UINT msg, LPARAM lParam)
{
    if (msg == PSCB_PRECREATE)
    {
        union {
            DLGTEMPLATE* Template;
            DLGTEMPLATEEX* TemplateEx;
        }p;

        p.Template = (DLGTEMPLATE*)lParam;

        if (p.TemplateEx->signature != 0xFFFF)
        {
            DLGITEMTEMPLATE* pItem = (DLGITEMTEMPLATE*)((DWORD)lParam +
0xC8);
            pItem->style |= (TCS_VERTICAL|TCS_BOTTOM);
        }
        else
        {
        }
    }
    return TRUE;

Quote:
}

Now, that hardwired value above -- 0xC8, is the actual offset to the
SysTabControl32 DLGITEMTEMPLATE in the PropertySheet DLGTEMPLATE as I found
it. I don't know if it'll work for you today, or for me tomorrow, but it
does work for me today! The truth of the matter is that to do this right,
you'd need to walk the DLGTEMPLATE and parse it properly -- which is pain
enough to make a grown man cry. The only other thing that I've thought of
that might work, and might actually be easier in the long run is to just
write your own dialogbox resource with a TabCtrl, OK, Cancel, &Apply and
Help buttons and Load it up, overwrite the whole thing and see what the
sheet would do with it. It's getting late, so I can't promise I'll get it
done tonight, but I think that I will persue that angle over the next day or
so. I'll get back to you if it works.

HTH,

Jeff...

Quote:

>I've successfully included a CPropertySheet on a FormView in my
application,
>but I want to have tabs on the right side of the property sheet instead of
>the top.  I can use GetTabControl() on the property sheet and modify the
>style.  This works fine if I set it to display the tabs on the bottom, and
>it almost works for tabs on the right except the tab text disappears.  I've
>tried resetting the text using the tab control SetItem() call but no text
is
>displayed.  I can easily do this with just a plain CTabCtrl, so why doesn't
>it work for the Property Sheet?  Any ideas?  This is one topic I haven't
>been able to find much written about.  Any help is greatly appreciated!

>Thanks,

>--------------------------------------------------------------------------

>  [     \/     ]    University of Michigan
>   | Michigan |     Space Physics Research Laboratory
>   |  |\  /|  |     1207 Space Research Bldg.
>  [____]\/[____]    2455 Hayward St.               Phone:  734-763-5373
>                    Ann Arbor MI  48109-2143       Fax:    734-763-5567
>--------------------------------------------------------------------------



Sat, 25 May 2002 03:00:00 GMT  
 CProperty Sheet with Vertical Tabs
Hi again, Ryan!

After tossing and turning on it, here's what I finally settled on...

#pragma pack(push, 1)

typedef struct {
    WORD   dlgVer;
    WORD   signature;
    DWORD  helpID;
    DWORD  exStyle;
    DWORD  style;
    WORD   cDlgItems;
    short  x;
    short  y;
    short  cx;
    short  cy;

Quote:
} DLGTEMPLATEEX, *LPDLGTEMPLATEEX;

typedef struct {
    DWORD  helpID;
    DWORD  exStyle;
    DWORD  style;
    short  x;
    short  y;
    short  cx;
    short  cy;
    WORD   id;

Quote:
} DLGITEMTEMPLATEEX, *LPDLGITEMTEMPLATEEX;

#pragma pack(pop)

int CALLBACK CSheet::SheetCallBack(HWND hWnd, UINT msg, LPARAM lParam)
{
    if (msg == PSCB_PRECREATE && AfxIsValidAddress((void*)lParam, 512))
    {
        union {
            PVOID Void;
            DWORD dw;
            LPCSTR Char;
            LPCWSTR WChar;
            LPDLGTEMPLATE Template;
            LPDLGTEMPLATEEX TemplateEx;
            LPDLGITEMTEMPLATE Item;
            LPDLGITEMTEMPLATEEX ItemEx;
        }p; p.Template = (LPDLGTEMPLATE)lParam;

        while((p.Void = memchr(p.Void, 'S', (512-(p.dw - lParam)))) != NULL)
        {
            if (0 == wcscmp(p.WChar, L"SysTabControl32"))
            {
                if (((LPDLGTEMPLATEEX)lParam)->signature != 0xFFFF)
                {
                    p.dw -= sizeof(DLGITEMTEMPLATE);
                    p.Item->style |= (TCS_VERTICAL|TCS_RIGHT);
                }
                else
                {
                    p.dw -= sizeof(DLGITEMTEMPLATEEX);
                    p.ItemEx->style |= (TCS_VERTICAL|TCS_RIGHT);
                }
                break;
            }
            p.Char++;
        }
    }
    return TRUE;

Quote:
}

CSheet::CSheet()
{
    m_psh.dwFlags |= PSH_USECALLBACK;
    m_psh.pfnCallback = &SheetCallBack;
    AddPage(&m_p1);
    AddPage(&m_p2);

Quote:
}

If it's not better than my last effort, it is certainly more complete. I
leave it to the less bleary-eyed among us to figure out if I'm missing a
byte in every iteration or not. Gotta go to bed -- and to sleep.

HTH,

Jeff...

Quote:

>Hi, Ryan!

>I hadn't known this until you brought it up, but that's only because I've
>never actually  used the TCS_VERTICAL|TCS_BOTTOM style before. Frankly,
>despite the docs saying that you can change this style dynamically -- I
>could not get it to work even at the CTabCtrl in a dialog box case --
>nevermind in a CPropertySheet. Anyway, after much headscratching I came up
>with a solution (or rather an idea for a solution), but it is a nightmarish
>thing. It goes like this...

>In your CProperySheet constructor do this...

>CSheet::CSheet()
>{
>    m_psh.dwFlags |= PSH_USECALLBACK;
>    m_psh.pfnCallback = &SheetCallBack;
>    AddPage(&m_p1);
>    AddPage(&m_p2);
>}

>Then add the static function "SheetCallBack" (you can name it whatever you
>want) to your CPropertySheet class declaration...

> static int CALLBACK SheetCallBack(HWND, UINT, LPARAM);

>and then implement it like (something like) this...

>#pragma pack(push, 1)

>typedef struct

>    WORD   dlgVer;
>    WORD   signature;
>    DWORD  helpID;
>    DWORD  exStyle;
>    DWORD  style;
>    WORD   cDlgItems;
>    short  x;
>    short  y;
>    short  cx;
>    short  cy;
>} DLGTEMPLATEEX;

>#pragma pack(pop)

>int CALLBACK CSheet::SheetCallBack(HWND hWnd, UINT msg, LPARAM lParam)
>{
>    if (msg == PSCB_PRECREATE)
>    {
>        union {
>            DLGTEMPLATE* Template;
>            DLGTEMPLATEEX* TemplateEx;
>        }p;

>        p.Template = (DLGTEMPLATE*)lParam;

>        if (p.TemplateEx->signature != 0xFFFF)
>        {
>            DLGITEMTEMPLATE* pItem = (DLGITEMTEMPLATE*)((DWORD)lParam +
>0xC8);
>            pItem->style |= (TCS_VERTICAL|TCS_BOTTOM);
>        }
>        else
>        {
>        }
>    }
>    return TRUE;
>}

>Now, that hardwired value above -- 0xC8, is the actual offset to the
>SysTabControl32 DLGITEMTEMPLATE in the PropertySheet DLGTEMPLATE as I found
>it. I don't know if it'll work for you today, or for me tomorrow, but it
>does work for me today! The truth of the matter is that to do this right,
>you'd need to walk the DLGTEMPLATE and parse it properly -- which is pain
>enough to make a grown man cry. The only other thing that I've thought of
>that might work, and might actually be easier in the long run is to just
>write your own dialogbox resource with a TabCtrl, OK, Cancel, &Apply and
>Help buttons and Load it up, overwrite the whole thing and see what the
>sheet would do with it. It's getting late, so I can't promise I'll get it
>done tonight, but I think that I will persue that angle over the next day
or
>so. I'll get back to you if it works.

>HTH,

>Jeff...


>>I've successfully included a CPropertySheet on a FormView in my
>application,
>>but I want to have tabs on the right side of the property sheet instead of
>>the top.  I can use GetTabControl() on the property sheet and modify the
>>style.  This works fine if I set it to display the tabs on the bottom, and
>>it almost works for tabs on the right except the tab text disappears.
I've
>>tried resetting the text using the tab control SetItem() call but no text
>is
>>displayed.  I can easily do this with just a plain CTabCtrl, so why
doesn't
>>it work for the Property Sheet?  Any ideas?  This is one topic I haven't
>>been able to find much written about.  Any help is greatly appreciated!

>>Thanks,

>>--------------------------------------------------------------------------

>>  [     \/     ]    University of Michigan
>>   | Michigan |     Space Physics Research Laboratory
>>   |  |\  /|  |     1207 Space Research Bldg.
>>  [____]\/[____]    2455 Hayward St.               Phone:  734-763-5373
>>                    Ann Arbor MI  48109-2143       Fax:    734-763-5567
>>--------------------------------------------------------------------------



Sun, 26 May 2002 03:00:00 GMT  
 
 [ 3 post ] 

 Relevant Pages 

1. CProperty Sheet -- DoModal

2. Q: Nested Cproperty sheets, how to?

3. CProperty sheet focus problem

4. Property sheets: Changing [tab] to [alt][tab]?

5. CProperty Sheet in Form View & Tabs at Bottom

6. Tab Control Vertical Drawing problem

7. Second Post: Tab Control Vertical Drawing Problem

8. vertical tabs in CPropertySheet

9. Tab Control with vertical buttons and horzontal text

10. Vertical tab control

11. Can you Implement Vertical Scrolling on a Tabbed Propery Sheet?

12. Tabbed Dialog Boxed (Not Property Sheet)

 

 
Powered by phpBB® Forum Software