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
Solved

Precise alignment of text with toolbar button

Posted on 2013-11-25
7
359 Views
Last Modified: 2013-11-26
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
Comment
Question by:Knut Hunstad
  • 5
  • 2
7 Comments
 
LVL 33

Expert Comment

by:sarabande
ID: 39676872
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
 
LVL 8

Author Comment

by:Knut Hunstad
ID: 39676987
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
 
LVL 8

Author Comment

by:Knut Hunstad
ID: 39676997
Oh, I forgot:

GetSystemMetrics(SM_CXSIZEFRAME);

returns 9...
0
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

 
LVL 33

Accepted Solution

by:
sarabande earned 500 total points
ID: 39677199
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
 
LVL 8

Author Comment

by:Knut Hunstad
ID: 39677253
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
 
LVL 8

Author Comment

by:Knut Hunstad
ID: 39677322
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
 
LVL 8

Author Closing Comment

by:Knut Hunstad
ID: 39677331
Although you didn't provide an exact answer, you helped me search in the right direction.

Thank you!
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering 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

This article describes a technique for converting RTF (Rich Text Format) data to HTML and provides C++ source that does it all in just a few lines of code. Although RTF is coming to be considered a "legacy" format, it is still in common use... po…
zlib is a free compression library (a DLL) on which the popular gzip utility is built.  In this article, we'll see how to use the zlib functions to compress and decompress data in memory; that is, without needing to use a temporary file.  We'll be c…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…

839 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