Solved

Precise alignment of text with toolbar button

Posted on 2013-11-25
7
362 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
[X]
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
  • 5
  • 2
7 Comments
 
LVL 34

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
PeopleSoft Has Never Been Easier

PeopleSoft Adoption Made Smooth & Simple!

On-The-Job Training Is made Intuitive & Easy With WalkMe's On-Screen Guidance Tool.  Claim Your Free WalkMe Account Now

 
LVL 34

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

Online Training Solution

Drastically shorten your training time with WalkMe's advanced online training solution that Guides your trainees to action. Forget about retraining and skyrocket knowledge retention rates.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Visual Studio Exe Issue, 12 38
Winform not working on 64 bit machine 31 104
What is MicroStrategy.NET? 2 83
Mobile apps - web/native or hybrid? 1 72
Entering time in Microsoft Access can be difficult. An input mask often bothers users more than helping them and won't catch all typing errors. This article shows how to create a textbox for 24-hour time input with full validation politely catching …
Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
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…
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaac…

726 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