• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 382
  • Last Modified:

Precise alignment of text with toolbar button

Hi!

First: I hope this is the right forum for this question, I couldn't find any "MFC" forum?

I am struggling to align a static text directly under a toolbar button in an MFC dialog. But I can't get it totally precise, it seems to be offset to the left by a small amount.

// I start finding the existing window of the text to be moved. It should keep it's vertical //placement.

  CRect rcText;
  GetDlgItem(textId)->GetWindowRect(rcText);
  ScreenToClient(rcText);

  // Then I find the window of the button
  int nIndex = m_wndToolBar.GetToolBarCtrl().CommandToIndex(buttonId);
  CRect rcButton;
  m_wndToolBar.GetToolBarCtrl().GetItemRect(nIndex, &rcButton);

  // I change the left/right values of the window of the text
    rcText.left = rcButton.left;
    rcText.right = rcButton.right;
    GetDlgItem(textId)->MoveWindow(rcText, TRUE);

but the text ends up a little too far to the left. I expect GetItemRect is returning it's coordinates relative to some client window upperleft corner inside the toolbar. But how do I find those values? Calling GetClientRect on the toolbar has both left and top 0.

Thanks for any help!
0
Knut Hunstad
Asked:
Knut Hunstad
  • 5
  • 2
1 Solution
 
sarabandeCommented:
Calling GetClientRect on the toolbar has both left and top 0.
you can try to calling GetWindowRect(...) for the toolbar window and the window you get by  m_wndToolBar.GetParent().GetWindowRect(...). the difference of the TopLeft points of the rectangles you get should be the offset you need to add to the text control.

if your dialog is parent window of the toolbar you also could try ScreenToClient member function though I don't know whether the function works for rectangles outside of the client area.

another way is to consider widths of frames which you could retrieve by GetSystemMetrics, for example

rcText.left += GetSystemMetrics(SM_CXSIZEFRAME);

Open in new window


a list of all metrics codes can be found at

http://msdn.microsoft.com/en-us/library/windows/desktop/ms724385(v=vs.85).aspx

Sara
0
 
Knut HunstadAuthor Commented:
Thank you for what seems like a very valid tip, I was sure you got the solution. Only it doesn't quite work, now the text comes a little too much to the right!

I checked that the dialog is the parent of both the toolbar and the static text.

m_wndToolBar.GetParent().GetWindowRect() gives a left 9 units lower than m_wndToolBar.GetWindowRect(). But if I add 9 to the text horizontal placement, it goes noticably to far right!

By hardcoding I can find the correct offset for this display is 6.

And I am still wondering how I can get that parameter correctly?
0
 
Knut HunstadAuthor Commented:
Oh, I forgot:

GetSystemMetrics(SM_CXSIZEFRAME);

returns 9...
0
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

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.

 
sarabandeCommented:
the size of the frame and the offset to the toolbar is identical. that is an expected result and means that the GetItemRect returns client coordinates.

the offset still missing could be the offset from the toolbar control to the window that you get by m_wndToolBar.GetToolBarCtrl().


if that is 0, the offset you have to consider could be the offset in the toolbar to the first button. you could retrieve that by calling the GetItemRect for the first button.


how is the text displayed in the control? is it centered or left-aligned? are you sure that the text fits to the button at all? did you consider to add the text to the bitmap of the button rather than making an overlay with a text control of the parent window? you also could override the OnPaint member function of the dialog and make the drawings directly to the button. that would keep the bitmap as it is. you also could derive from toolbar class and then use the OnPaint of the derived toolbar class to do the text drawings. that would be the best design if possible.

Sara
0
 
Knut HunstadAuthor Commented:
Well, m_wndToolBar.GetToolBarCtrl().GetWindowRect and m_wndToolBar.GetWindowRect return exactly the same. GetItemRect for the first button returns 0 for left and top (as specified in the documentation, which for once is quite specific).

The text fits the button, yes (I calculate the necessary dimension with DrawText first and am quite confident that this part is correct. I have done other tests to verify that the problem is to find the offset from the main client area (parent of both toolbar and text) to the buttons). To be more specific about what I'm doing, I want to center align text under one or several buttons in the toolbar, not overlay anything on the buttons.

I am trying to avoid changing anything more than I have to in existing code, that's why I'm doing it this way.

And somehow it must be possible to calculate this offset, right?
0
 
Knut HunstadAuthor Commented:
Finally! The trick was to understand what window's ScreenToClient/ClientToScreen you should call:

  CRect rcToolbar;
 
 // I could actually just as well initialize rcToolbar with zeros, since
// I only need the upperleft corner, which will be (0, 0) after the next function anyway
// But if you need bottom or right, do this
  m_wndToolBar.GetClientRect(&rcToolbar);

  m_wndToolBar.ClientToScreen(rcToolbar);
 // rcToolbar is now in absolute screen coordinates

  ScreenToClient(rcToolbar);
 // rcToolbar is now the toolbar client area's offset from my dialog's client area.

  const int rcHorOffset = rcToolbar.left; // Voilá

This gives me an rcHorOffset of 6 in my case, which is precise.
0
 
Knut HunstadAuthor Commented:
Although you didn't provide an exact answer, you helped me search in the right direction.

Thank you!
0

Featured Post

Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

  • 5
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now