From: JY on
Hi,

I have a Wizard style property sheet, and when I try to set its title using
SetTitle in its constructor, the title doesn't show up.

Before that, I've added pages to the property sheet, which have the Title
Bar" of all the pages set to True, but nothing in the "Caption" property. If
I add a string to the "Caption" property it gets displayed properly, but if I
do it programmatically it just doesn't work.

I've also tried SetWindowText() in OnInitDialog() of the property pages, but
that too does not work.

How do I set the title programmatically?

TIA,
Jy
From: John H. on
JY wrote:
> Hi,
>
> I have a Wizard style property sheet, and when I try to set its title using
> SetTitle in its constructor, the title doesn't show up.
>
> Before that, I've added pages to the property sheet, which have the Title
> Bar" of all the pages set to True, but nothing in the "Caption" property. If
> I add a string to the "Caption" property it gets displayed properly, but if I
> do it programmatically it just doesn't work.
>
> I've also tried SetWindowText() in OnInitDialog() of the property pages, but
> that too does not work.
>
> How do I set the title programmatically?

In the property page's constructor, assign the title and turn on the
PSP_USETITLE style. e.g.:

class CMyPropertyPage : public CPropertyPage
{
public:
CMyPropertyPage() :
CPropertyPage(IDD_PROPPAGE_SMALL)
{
_stprintf(title, _T("My title here"));
m_psp.pszTitle = title;
m_psp.dwFlags |= PSP_USETITLE;
}
private:
TCHAR title[10];
};
From: Pete Delgado on

"John H." <oldman_fromthec(a)yahoo.com> wrote in message
news:99af9a41-cdf9-42e2-9988-b560e0253f24(a)r18g2000yqd.googlegroups.com...
> JY wrote:
>> Hi,
>>
>> I have a Wizard style property sheet, and when I try to set its title
>> using
>> SetTitle in its constructor, the title doesn't show up.
>>
>> Before that, I've added pages to the property sheet, which have the Title
>> Bar" of all the pages set to True, but nothing in the "Caption" property.
>> If
>> I add a string to the "Caption" property it gets displayed properly, but
>> if I
>> do it programmatically it just doesn't work.
>>
>> I've also tried SetWindowText() in OnInitDialog() of the property pages,
>> but
>> that too does not work.
>>
>> How do I set the title programmatically?
>
> In the property page's constructor, assign the title and turn on the
> PSP_USETITLE style. e.g.:
>
> class CMyPropertyPage : public CPropertyPage
> {
> public:
> CMyPropertyPage() :
> CPropertyPage(IDD_PROPPAGE_SMALL)
> {
> _stprintf(title, _T("My title here"));
> m_psp.pszTitle = title;
> m_psp.dwFlags |= PSP_USETITLE;
> }
> private:
> TCHAR title[10];
> };

The above code should crash. You attempt to copy a 14 element (13 characters
+ terminating null) sequence into a 10 element array. Since you are using a
string literal anyway, why not just set the pszTitle member to the literal
rather than attempting to copy it into a class member?

-Pete


From: Joseph M. Newcomer on
On Tue, 6 Apr 2010 09:21:15 -0700 (PDT), "John H." <oldman_fromthec(a)yahoo.com> wrote:

>JY wrote:
>> Hi,
>>
>> I have a Wizard style property sheet, and when I try to set its title using
>> SetTitle in its constructor, the title doesn't show up.
>>
>> Before that, I've added pages to the property sheet, which have the Title
>> Bar" of all the pages set to True, but nothing in the "Caption" property. If
>> I add a string to the "Caption" property it gets displayed properly, but if I
>> do it programmatically it just doesn't work.
>>
>> I've also tried SetWindowText() in OnInitDialog() of the property pages, but
>> that too does not work.
>>
>> How do I set the title programmatically?
>
>In the property page's constructor, assign the title and turn on the
>PSP_USETITLE style. e.g.:
>
>class CMyPropertyPage : public CPropertyPage
>{
> public:
> CMyPropertyPage() :
> CPropertyPage(IDD_PROPPAGE_SMALL)
> {
> _stprintf(title, _T("My title here"));
****
This is HORRIBLE programming! sprintf and all its variants are funamentally DEAD and
should be! In fact, "My title here" takes more than 10 characters, so in fact this code
is erroneous as written, a primary example of why this kind of code should NEVER be used!
(As written, you will clobber the block header of the next block in the storage allocator,
resulting in either an assertion failure from the debug allocator or a crash from the
release allocator [most likely an access faultor an unhandled int3] some tens of millions
of instructions later, making it impossible to find that this is what caused the problem!)

The correct form would have been to declare title as a CString, and write
title.Format_T("My title here"));
// Note this is unnecessary if a literal is used
// unless the format string has %s, %d, etc. in it
// a simple assignment works fine!
// If it IS a literal, why didn't it appear on the next line as the RHS
// of the assignment? Then you don't need silly intermediate buffers!
// Or you could have declared
LPTSTR title;
// so you didn't have to worry about the allocation!
m_psp_pszTItle =(LPCTSTR)title;
*****
>> m_psp.dwFlags |= PSP_USETITLE;
>> }
>> private:
>> TCHAR title[10];
****
CString title;
//NEVER use a fixed-size array like this, especially one with very small limits!
*** > m_psp.pszTitle = title;
> m_psp.dwFlags |= PSP_USETITLE;
> }
> private:
> TCHAR title[10];
>};
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: John H. on
Pete Delgado wrote:
> The above code should crash. You attempt to copy a 14 element (13 characters
> + terminating null) sequence into a 10 element array. Since you are using a
> string literal anyway, why not just set the pszTitle member to the literal
> rather than attempting to copy it into a class member?

For those looking for a little safer example:

class CMyPropertyPage : public CPropertyPage
{
public:
CMyPropertyPage(UINT nIDTemplate, CString csTitle) :
CPropertyPage(nIDTemplate),
m_csTitle(csTitle)
{
m_psp.pszTitle = m_csTitle;
m_psp.dwFlags |= PSP_USETITLE;
}
private:
CString const m_csTitle;
};

So then you can doing something like the following (assuming you have
a dialog template resource IDD_PROPPAGE_SMALL and a string table
resource with an entry IDS_MY_TITLE):

#include "resource.h"
int main()
{
CPropertySheet sheet;
CMyPropertyPage page(IDD_PROPPAGE_SMALL,
CString((LPCTSTR)IDS_MY_TITLE));
sheet.AddPage(&page);
sheet.SetWizardMode();
sheet.DoModal();
return 0;
}