Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Setting text of a checkbox to wide enough for any string

Posted on 2006-05-25
25
Medium Priority
?
397 Views
Last Modified: 2013-11-20
Ah hello.

I am trying to size a checkbox so that it will fit on any text I load from my stringtable.  'pButton' is my checkbox in the code below.

I am finding that if I do a simple

      CDC* pDC = pButton->GetDC();
      pDC->SelectObject( pButton->GetFont() );
      CString strScale( _T( "This is a long string" ) );
      CRect rectRequired;
      pButton->GetWindowRect( &rectRequired );
      ScreenToClient( &rectRequired );

      pDC->DrawText( strScale, rectRequired, DT_CALCRECT ); // Just calculate, dont draw the text

      pButton->MoveWindow( &rectRequired );

      pButton->SetWindowText( strScale );

The text is still not all being shown due to some of the 'rectRequired' being used for the actual checkbox itself.

I have tried using AdjustWindowRectEx but that makes no difference.

I tried what is suggested at http:Q_10248099.html; adding on the width of the bitmap still gives a rectangle too small.

What do you think ?

TIA
0
Comment
Question by:mrwad99
  • 11
  • 10
  • 4
25 Comments
 
LVL 22

Expert Comment

by:mahesh1402
ID: 16760665
just dont draw the the text using Button DC while calculating rect using DT_CALCRECT .

In your code I just used DC created using CPaintDC.. and its giving me correct result.
NOTE : Also I have also NOT selected any font in DC.

something like following

     CPaintDC dc(this);

     CString strScale( _T( "This is a long string" ) );
     CRect rectRequired;

     pButton->GetWindowRect( &rectRequired );
     ScreenToClient( &rectRequired );

     dc.DrawText( strScale, rectRequired, DT_CALCRECT ); // Just calculate, dont draw the text

     pButton->MoveWindow( &rectRequired );

     pButton->SetWindowText( strScale );

-MAHESH
0
 
LVL 19

Author Comment

by:mrwad99
ID: 16761205
OK that works...

but what is the difference between using a device context obtained from the dialog, and one obtained from the button ?

Thanks.
0
 
LVL 19

Author Comment

by:mrwad99
ID: 16761224
Also, from MSDN:

"A CPaintDC object can only be used when responding to a WM_PAINT message, usually in your OnPaint message-handler member function."

I am setting the size of this button in both my OnInitDialog and the OnSize() for my dialog (it can be resized).

?!?
0
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!

 
LVL 22

Expert Comment

by:mahesh1402
ID: 16761421
>>but what is the difference between using a device context obtained from the dialog, and one obtained from the button
>>A CPaintDC object can only be used when responding to a WM_PAINT message,

I just observed DrawText() function with  DT_CALCRECT is not calculating RECT width correctly when using with button DC.

I just used CPaintDC for example ...you may use dialogs DC using GetDC()..

-MAHESH

0
 
LVL 22

Expert Comment

by:mahesh1402
ID: 16761473
BUT by testing more its seems that problem not seems with DC .....just ignoring Selecting font in DC is also giving correct output.

This is working :

    CDC* pDC = pButton->GetDC();

    // pDC->SelectObject( pButton->GetFont() );

     CString strScale( _T( "This is a long string" ) );
     CRect rectRequired;
     pButton->GetWindowRect( &rectRequired );

     ScreenToClient( &rectRequired );
     pDC->DrawText( strScale, rectRequired, DT_CALCRECT ); // Just calculate, dont draw the text

     pButton->MoveWindow( &rectRequired );
     pButton->SetWindowText( strScale );

-MAHESH
0
 
LVL 19

Author Comment

by:mrwad99
ID: 16767429
OK this is strange.  You will remember from previous questions (like http:Q_21762261.html) that we had to select the font of the control, which, in the case of the question above, was a static control, in order to get the size set to fully accomodate the required text.

Yet it seems here (as you have proved) that selecting the font of the checkbox (well, CButton) produces the wrong result.

Why is this ?  I am concerned since there appears to be no standard way of setting any control's size to fully accomodate text, as two different methods are required for two different controls.

(Points doubled).
0
 
LVL 22

Expert Comment

by:mahesh1402
ID: 16767644
>>Yet it seems here (as you have proved) that selecting the font of the checkbox (well, CButton) produces the wrong result.

May be this is beause of the default control font.

Because when I tried to set checkbox default font to some other font lets say arial then even selecting font in DC is giving me correct result :

      CDC* pDC = pButton->GetDC();

      CFont chkFont;
      chkFont.CreatePointFont(150,"Arial");
      pButton.SetFont(&chkFont);

     pDC->SelectObject(pButton.GetFont() );

     CString strScale( _T( "This is a long string" ) );
     CRect rectRequired;
     pButton->GetWindowRect( &rectRequired );

     ScreenToClient( &rectRequired );

     pDC->DrawText( strScale, &rectRequired, DT_CALCRECT); // Just calculate, dont draw the text

     pButton->MoveWindow( &rectRequired );
     pButton->SetWindowText( strScale );

-MAHESH
0
 
LVL 22

Expert Comment

by:mahesh1402
ID: 16767659
Read Correct As :

 pDC->SelectObject(pButton->GetFont() );
0
 
LVL 19

Author Comment

by:mrwad99
ID: 16767777
>> May be this is beause of the default control font.

OK, so you are saying that GetFont() returns the incorrect font for the control ?  Surely that is a bug ?
0
 
LVL 22

Expert Comment

by:mahesh1402
ID: 16767847
>>so you are saying that GetFont() returns the incorrect font for the control ?

NO GetFont() returns correct Font for the control....you may trace that by using pButton->GetFont()->GetLogFont(..).

It seems to be somewhat differnet behaviour for checkbox button and CStatic text..even with GetTextExtent its calculating wrong width with default font...

Even you change your dialog's font in resource editor it will give you same wrong output....I just want to point-out that setting Font for the control manually works for getting correct rect using DT_CALCRECT..

-MAHESH
0
 
LVL 19

Author Comment

by:mrwad99
ID: 16767971
Fantastic.  It seems again though that there is different behaviour when creating a control via Create(...), as opposed to the control being on a dialog resource.

Consider this short code:

BOOL CDialogAppDlg::OnInitDialog()
{

#define IDC_BUTTON 1355
      CDialog::OnInitDialog();

      CString str(_T("Short"));
      CRect rcEmpty;
      rcEmpty.SetRectEmpty();
      m_wndButton.Create( str, WS_VISIBLE | WS_CHILD | BS_CHECKBOX, rcEmpty, this, IDC_BUTTON );

      CDC* pDC =  m_wndButton.GetDC();

      CString strScale( _T( "This is a long string" ) );
      CRect rectRequired;
      m_wndButton.GetWindowRect( &rectRequired );

      ScreenToClient( &rectRequired );
      pDC->DrawText( strScale, rectRequired, DT_CALCRECT ); // Just calculate, dont draw the text

      m_wndButton.MoveWindow( &rectRequired );
      m_wndButton.SetWindowText( strScale );

      m_wndButton.ReleaseDC( pDC );

      return TRUE;  // return TRUE  unless you set the focus to a control
}

Two strange things occur here.  Firstly, the font is bold, and larger than normal.  Secondly, the control is not big enough to hold all the text.

What is happening here ?

Thanks for the help so far.
0
 
LVL 22

Expert Comment

by:mahesh1402
ID: 16768067
Yes this also different behaviour but in this case also changing default font works to calculate right width ...

      CFont chkFont;
      chkFont.CreatePointFont(150,"Arial");
      m_wndButton.SetFont(&chkFont);

     pDC->SelectObject(m_wndButton.GetFont());


But in this case if you try to get default font face or font weight of controls default font using m_wndButton.GetFont()->GetLogFont(&lf) then it will fail...because in this case for dynamic controls its not getting proper font..but changing default font in this case too works.

-MAHESH
0
 
LVL 19

Author Comment

by:mrwad99
ID: 16768142
>> but in this case also changing default font works to calculate right width ...

I still cannot get the control's width to be set correctly.  This is my (new) code:

BOOL CDialogAppDlg::OnInitDialog()
{
#define IDC_BUTTON 1355
      CDialog::OnInitDialog();

      CString str(_T("Short"));
      CRect rcEmpty;
      rcEmpty.SetRectEmpty();
      m_wndButton.Create( _T(""), WS_VISIBLE | WS_CHILD | BS_CHECKBOX, rcEmpty, this, IDC_BUTTON );

      CFont chkFont;
      chkFont.CreatePointFont(150,"Arial");
      m_wndButton.SetFont(&chkFont);

      CDC* pDC =  m_wndButton.GetDC();

      CString strScale( _T( "This is a long string" ) );
      CRect rectRequired;
      m_wndButton.GetWindowRect( &rectRequired );

      ScreenToClient( &rectRequired );
      pDC->DrawText( strScale, rectRequired, DT_CALCRECT ); // Just calculate, dont draw the text

      m_wndButton.MoveWindow( &rectRequired );
      m_wndButton.SetWindowText( strScale );

      pDC->SelectObject(m_wndButton.GetFont());
      m_wndButton.ReleaseDC( pDC );


      return TRUE;  // return TRUE  unless you set the focus to a control
}

The width is still shorter than required (http://img119.imageshack.us/img119/1930/untitled3si1.jpg).

Also, why when I do not set a font, i.e. remove the line

m_wndButton.SetFont(&chkFont);

is the font *still* large and bold ?

??
0
 
LVL 22

Expert Comment

by:mahesh1402
ID: 16768242
You are selecting object in DC after call to DrawText() select it in DC before DrawText()....

     CString str(_T("Short"));
     CRect rcEmpty;
     rcEmpty.SetRectEmpty();
     m_wndButton.Create( str, WS_VISIBLE | WS_CHILD | BS_CHECKBOX, rcEmpty, this, IDC_BUTTON );

     CDC* pDC =  m_wndButton.GetDC();

      

      CFont chkFont;
      chkFont.CreatePointFont(150,"Arial");
      m_wndButton.SetFont(&chkFont);

      pDC->SelectObject(m_wndButton.GetFont());
     
     CString strScale( _T( "This is a long string" ) );
     CRect rectRequired;
     m_wndButton.GetWindowRect( &rectRequired );

     ScreenToClient( &rectRequired );
     pDC->DrawText( strScale, rectRequired, DT_CALCRECT ); // Just calculate, dont draw the text

     m_wndButton.MoveWindow( &rectRequired );
     m_wndButton.SetWindowText( strScale );

     m_wndButton.ReleaseDC( pDC );

-MAHESH
0
 
LVL 19

Author Comment

by:mrwad99
ID: 16768630
OK thanks that solves it.  However, when I do not add a font, and use the default, I still get a larger, bolder font:

CString str(_T("Short"));
      CRect rcEmpty;
      rcEmpty.SetRectEmpty();
      m_wndButton.Create( str, WS_VISIBLE | WS_CHILD | BS_CHECKBOX, rcEmpty, this, IDC_BUTTON );

      CDC* pDC =  m_wndButton.GetDC();

        // NOTE: NO NEW FONT EXPLICITLY SPECIFIED

      //CFont chkFont;
      //chkFont.CreatePointFont(150,"Arial");
      //m_wndButton.SetFont(&chkFont);

      //pDC->SelectObject(m_wndButton.GetFont());

      CString strScale( _T( "This is a long string" ) );
      CRect rectRequired;
      m_wndButton.GetWindowRect( &rectRequired );

      ScreenToClient( &rectRequired );
      pDC->DrawText( strScale, rectRequired, DT_CALCRECT ); // Just calculate, dont draw the text

      m_wndButton.MoveWindow( &rectRequired );
      m_wndButton.SetWindowText( strScale );

      m_wndButton.ReleaseDC( pDC );

Where is this large font coming from?

Thanks again for the continued help :)
0
 
LVL 22

Expert Comment

by:mahesh1402
ID: 16769002
>>Where is this large font coming from?

Right now I cant predict where its coming from but this seems to be defualt behaviour with dynamic controls.....
I have tested with other controls like pushbutton and its also creating them with bold font....

Seems with Create() its bydefault making control font weight as bold ( LOGFONT with FW_BOLD )..

SO I think we need to set font for each control with FW_NORMAL as weight.. you may just fillup LOGFONT structure with weight FW_NORMAL and other default parameters like face "Ms Sans Serif" etc and pass to CreateFontIndirect() to change it !!!

-MAHESH
0
 
LVL 45

Expert Comment

by:AndyAinscow
ID: 16769244
Interesting.

Using this code
#define IDC_BUTTON 1355
      CString str(_T("Short"));
     CRect rcEmpty(10, 10, 11, 11);
 //    rcEmpty.SetRectEmpty();
     m_wndButton.Create( str, WS_BORDER | WS_VISIBLE | WS_CHILD, rcEmpty, this, IDC_BUTTON );
//       m_wndButton.SubclassDlgItem(IDC_CHECK1, this);

     CDC* pDC =  m_wndButton.GetDC();

        // NOTE: NO NEW FONT EXPLICITLY SPECIFIED

     //CFont chkFont;
     //chkFont.CreatePointFont(150,"Arial");
     //m_wndButton.SetFont(&chkFont);

     //pDC->SelectObject(m_wndButton.GetFont());

     CString strScale( _T( "This is a long string" ) );
     CRect rectRequired;
     m_wndButton.GetWindowRect( &rectRequired );

     ScreenToClient( &rectRequired );
     pDC->DrawText( strScale, rectRequired, DT_CALCRECT ); // Just calculate, dont draw the text

       m_wndButton.CalcWindowRect(&rectRequired);   //Because I have the border
     m_wndButton.MoveWindow( &rectRequired );
     m_wndButton.SetWindowText( strScale );

     m_wndButton.ReleaseDC( pDC );


I have displayed the border so that one sees just where the control is and removed the checkbox style.  It does display the button with the correct width.  Putting it back to a BS_CHECKBOX style and the width is apparently the same.  
Conclusion - the DrawText is working *correctly*, it just doesn't understand that there needs to be room for the check box itself in the control.
0
 
LVL 22

Expert Comment

by:mahesh1402
ID: 16774405
As I said it seems dynamically created controls is not having same font as parent..When we place them in resource editor then it seems they having same font as parent...

But to resolve this we can just set font of controls to font of parents after creating controls immediately like this :

  m_wndButton.Create( str, WS_BORDER | WS_VISIBLE | WS_CHILD, rcEmpty, this, IDC_BUTTON );
  m_wndButton.SetFont( m_wndButton.GetParent()->GetFont());

-MAHESH
0
 
LVL 45

Assisted Solution

by:AndyAinscow
AndyAinscow earned 400 total points
ID: 16775334
The button is drawing BOTH text and image.  No matter what font is in the control the width from the DrawText with the DT_CALCRECT will NOT give the required width of the control.  You need to cope with the image width as well.

I don't know how to do that *properly*.  All I can suggest is a hack.  Another check box, invisible, no text.  See how wide it is and use that to fudge the width of the button control.
0
 
LVL 19

Author Comment

by:mrwad99
ID: 16785348
>> Another check box, invisible, no text.  See how wide it is and use that to fudge the width of the button control.

Yeah, but how ?  I need to get the size of the check alone.  The control will have whatever size I specify in the Create() function...

As I posted before, perhaps http:Q_10248099.html can help.  But I could not get it working, can either of you ??

I tried:

#ifndef OBM_CHECK
#define OBM_CHECK 32760
#endif

      HBITMAP hBmp = LoadBitmap(NULL, MAKEINTRESOURCE(OBM_CHECK));
      BITMAP bmp;
      if (hBmp != NULL)
      {
            GetObject(hBmp, sizeof(BITMAP), &bmp);
            TRACE(_T("%d wide, %d high\n"), bmp.bmWidth, bmp.bmHeight);
      }

// Other stuff

      pDC->DrawText( strScale, rectRequired, DT_CALCRECT ); // Just calculate, dont draw the text
      rectRequired.right+=bmp.bmWidth;

But that still gave me a missing part of my string (http://img64.imageshack.us/img64/4821/testaa4oy.jpg)

???
0
 
LVL 22

Accepted Solution

by:
mahesh1402 earned 600 total points
ID: 16787626
I would like to repeat comment I have made in your previous qestion : http:Q_21756060.html

You need to add some unites to this calculated width....

As you can see OBM_CHECK is a bitmap for checkbox check rect... bmp.bmWidth for OBM_CHECK will just return this bitmap width.. but if you closely look at your checkbox you will get that there is some pixel gap between checkbox bitmap and checkbox string..for example here in this case if you add 4 pixels you will get correct width.

    pDC->DrawText( strScale, rectRequired, DT_CALCRECT ); // Just calculate, dont draw the text
     rectRequired.right+=bmp.bmWidth;
     rectRequired.right+=4;

-MAHESH
0
 
LVL 45

Expert Comment

by:AndyAinscow
ID: 16787719
>> Another check box, invisible, no text.  See how wide it is and use that to fudge the width of the button control.

Yeah, but how ?  I need to get the size of the check alone.  



No you don't with the hack.  The width of the dummy button is the checkbox + spacing + borders.  That with the width of the text should give you the total width of the control.
0
 
LVL 19

Author Comment

by:mrwad99
ID: 16791661
>> The width of the dummy button is the checkbox + spacing + borders

Sorry Andy, but I cannot see how I can create just the check.  ***The control will have whatever size I specify*** when I

Create( ... )

it....?
0
 
LVL 45

Expert Comment

by:AndyAinscow
ID: 16791858
You create it in the resource editor.  Make it as narrow as you can to cope with the image.  (As I said it is a hack).
0
 
LVL 19

Author Comment

by:mrwad99
ID: 16827290
Many thanks both :o)
0

Featured Post

Technology Partners: 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!

Question has a verified solution.

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

If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
How can you see what you are working on when you want to see it while you to save a copy? Add a "Save As" icon to the Quick Access Toolbar, or QAT. That way, when you save a copy of a query, form, report, or other object you are modifying, you…

577 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