Solved

Precise alignment of text with toolbar button

Posted on 2013-11-25
7
366 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
Salesforce Has Never Been Easier

Improve and reinforce salesforce training & adoption using WalkMe's digital adoption platform. Start saving on costly employee training by creating fast intuitive Walk-Thrus for Salesforce. Claim your Free 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

Instantly Create Instructional Tutorials

Contextual Guidance at the moment of need helps your employees adopt to new software or processes instantly. Boost knowledge retention and employee engagement step-by-step with one easy solution.

Question has a verified solution.

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

This article shows how to make a Windows 7 gadget that extends its U/I with a flyout panel -- a window that pops out next to the gadget.  The example gadget shows several additional techniques:  How to automatically resize a gadget or flyout panel t…
This article describes how to add a user-defined command button to the Windows 7 Explorer toolbar.  In the previous article (http://www.experts-exchange.com/A_2172.html), we saw how to put the Delete button back there where it belongs.  "Delete" is …
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…
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.

691 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