How to make a dialog title right/left aligned - mfc

With the help of CWnd::SetWindowText method, I am able to set the desired caption, to my dailog based application. How can I make it left/right aligned?

To right-align dialog title, you need to set "Right Align Text" for the Dialog in the resource editor (corresponding extended style is WS_EX_RIGHT).
The WS_EX_LAYOUTRT style actually flips the dialog, so all controls are layed out from right-to-left. Title DOES get to the right, but the close button moves to the left. NOT what was asked in the original question.

There are few extended window styles like WS_EX_RIGHT to do that.
Here is a sample:
int CTestAlignDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialogEx::OnCreate(lpCreateStruct) == -1)
return -1;
ModifyStyleEx(0, WS_EX_LAYOUTRTL | WS_EX_RTLREADING);
return 0;
}

Related

C++ how to display text in child window at real time

This application creates a child window (which is the white box) when I right click anywhere, and destroys the child window after another right click. I have implemented the mechanics to expand and shrink the red rectangle through Direct 2D. I would like the child window to display the width and height of the rectangle at real time, as I make changes to it. I do not interact with the child window at all: it doesn't need an "x" button for closing and stuff; it just prints out a couple lines of data.
Here is what I have in my main window procedure:
case WM_RBUTTONUP:
{
DemoApp *pDemoApp = reinterpret_cast<DemoApp *>(static_cast<LONG_PTR>(
::GetWindowLongPtrW(hwnd, GWLP_USERDATA)));
pDemoApp->showTextBox = !pDemoApp->showTextBox; //showTextBox is a boolean
if (pDemoApp->showTextBox) {
POINTS cursor = MAKEPOINTS(lParam);
pDemoApp->child_hwnd = CreateWindowEx(
WS_EX_TOPMOST,
"LISTBOX",
"I dont need a title here",
WS_CHILDWINDOW,
cursor.x,
cursor.y,
100,
200,
pDemoApp->main_hwnd,
NULL,
HINST_THISCOMPONENT,
pDemoApp
);
ShowWindow(pDemoApp->child_hwnd, SW_SHOWNORMAL);
UpdateWindow(pDemoApp->child_hwnd);
}
else {
DestroyWindow(pDemoApp->child_hwnd);
}
}
break;
How may I go from here? I would like to know:
Is using Direct Write to draw text in the child window my only option? I see the dashed lines in the white box so I assume there must be a way to display plain text.
I used LISTBOX here, which is a predefined windows class name. How do I set a procedure for it? What else predefined class name can better suit my need? Or do I have to register a custom one;
I would like to drag the child window around, how can I set it up so that the system handles dragging for me.
Would popping a dialog box to display text be better than popping a child window?
Thanks.
Since you are using a Win32 LISTBOX control as the child window, then you have a couple of options for displaying the rectangle's dimensions in it:
give the ListBox the LBS_HASSTRINGS style, and add 1-2 items to it. Then, any time you change the rectangle, send LB_DELETESTRING and LB_ADDSTRING messages to the ListBox's HWND to display the updated dimensions as needed. A ListBox does not have a way to update an existing item, so to change an existing item's text, you have to remove the item and then re-add it with the new text.
give the ListBox an LBS_OWNERDRAW... style, and add 1-2 blank item(s) in it. Then have the ListBox's parent window handle WM_MEASUREITEM and WM_DRAWITEM notifications from the ListBox to display the rectangle's current dimensions in the item(s) as needed. Whenever the rectangle is changed, call InvalidateRect() on the ListBox's HWND to trigger a redraw.

How can I resize an application menu bar in a MFC application?

I am working with MFC and I have created succesfully custom-drawn menus. Each menu-item is measured and drawn correctly, except the mainlevel-items. The only thing I can't get done is redrawing the application menubar.
I attached two images:
The first shows a part of the menubar. The font Consolas 11pt is drawed correct. The width of the buttons is calculated correct, the buttons need to be spread over two rows.
The second image shows the same menubar with font Consolas 20pt. Now the menu needs three rows to contain all menu-items. However, the height for each separate row, is not updated. (while debugging, I see the MeasureItem override calculates the correct height for each menu-item). Below the menubar, there is a toolbar (BCGToolBar), which calculates the correct height for its bar.
So whatever the fontsize is, the Application Menu Bar will never change its height?
How can I resize the application menu bar in this MFC application?
Things I have tried so far is following lines of code in different orders:
RECT barRect;
barRect.top = 0;
barRect.left = 0;
barRect.bottom = 100;
barRect.right = 1020;
m_pMainWnd->RepositionBars(0, 0, 0, 2, &barRect);
m_pMainWnd->GetTopLevelFrame()->RecalcLayout();
m_pMainWnd->DrawMenuBar();
for (POSITION pos = m_pMainWnd->GetTopLevelFrame()->m_listControlBars.GetHeadPosition(); pos != NULL;)
{
CControlBar* controlBar = reinterpret_cast<CControlBar*>(m_pMainWnd->GetTopLevelFrame()->m_listControlBars.GetNext(pos));
controlBar = nullptr; //Let's see what we can do with this. Is the menuBar a ControlBar? Didnt think so.
}
m_pMainWnd->RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);
The first part is not an answer to the direct question but it should clarify why there is no need for it.
The menu is part of the global UI. Also the size of a menu items is part of the global settings.
If the user wants it, he can change the windows settings to get a larger menu.
I don't think it is a good way to change the standard behaviour. A UI should be stable, persistent and consistent. All programs should have the same look and feel. This includes the menu bar.
Now to your question.
You receive the WM_MEASUREITEM message. Respond to it and you can change the height for an onwerdraw menu.
See: http://www.codeguru.com/cpp/controls/menu/article.php/c3719/The-Easiest-Way-to-Code-the-Owner-Drawn-Menu.htm

Hiding an MFC dialog box

Ok so I am using this code to hide the taskbar icon of a dialog based MFC application(VC++). The taskbar icon and the dialog box hide whenever I click on the cross or the close buttons. But I can’t get this one thing right. Whenever I hit the close or the cross button from title bar, the dialog box first flickers and shows a sort of intermediate dialog box and then hides. This is very annoying. I am posting my code here after two days of vain effort. So guys please help me. Thanks in advance.
void CMyAppDlg::OnBnClickedCancel()
{
// TODO: Add your control notification handler code here
CWnd* pWnd;
pWnd = AfxGetMainWnd();
RemoveTaskbarIcon(pWnd);
pWnd->ModifyStyle(WS_VISIBLE, 0);
mVisible = FALSE;
}
BOOL CMyAppDlg::RemoveTaskbarIcon(CWnd* pWnd)
{
LPCTSTR pstrOwnerClass = AfxRegisterWndClass(0);
// Create static invisible window
if (!::IsWindow(mWndInvisible.m_hWnd))
{
if (!mWndInvisible.CreateEx(0, pstrOwnerClass, _T(""),
WS_POPUP,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL, 0))
return FALSE;
}
pWnd->SetParent(&mWndInvisible);
return TRUE;
}
Here are the screen shots of dialog box. When I press the close or cross button, the dialog box which looks like this in the first place turns into this for like less than half a second and then disappears (hides).
If you show your dialog using CDialog::DoModal() the framework will make sure your dialog is shown. There is only one way to prevent a modal dialog from being shown:
BEGIN_MESSAGE_MAP(CMyDialog, CDialog)
ON_WM_WINDOWPOSCHANGING()
END_MESSAGE_MAP()
BOOL CHiddenDialog::OnInitDialog()
{
CDialog::OnInitDialog();
m_visible = FALSE;
return TRUE;
}
void CHiddenDialog::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos)
{
if (!m_visible)
lpwndpos->flags &= ~SWP_SHOWWINDOW;
CDialog::OnWindowPosChanging(lpwndpos);
}
I think Paul DiLascia recommended the following. This is for modal dialogs only.
The following code can be put in OnInitDialog to move the dialog off-screen. You will need to implement a method for moving it back on-screen when appropriate.
CRect DialogRect;
GetWindowRect(&DialogRect);
int DialogWidth = DialogRect.Width();
int DialogHeight = DialogRect.Height();
MoveWindow(0-DialogWidth, 0-DialogHeight, DialogWidth, DialogHeight);
The answer from l33t looks good and is probably better but this is an alternative.
Maybe an obvious thing, but what happens when you do the hide before you reparent the dialog? Also what if you don't directly modify the window style but use ShowWindow(SW_HIDE)?
Finally, have you tried switching the dialog's window style to WS_CHILD before calling SetParent() and/or maybe moving it out of the client area so that the window isn't shown any more (MoveWindow(-1000, -1000) or something like that).

Automatically display vertical scrollbar in multiline text edit control

On a windows mobile device I have a mutliline text edit control that is set to read-only and has some static text displayed during it's display lifetime. I would like to only display a vertical scrollbar when it's actually useful (i.e. the text is larger than the display).
I can't easily figure out if the text is to large to display because of two reasons.
There is no horizontal scroll bar displayed so the text wraps.
Under windows mobile, the win32 routines to calculate the size of what text will display does not work correctly. They return a incorrect rectangle.
The edit control must tell the scroll bar what it's scroll range is at some point. I was wondering if I could get in between then and hide the scroll bar if it's not going to be used.
This is how I solved this problem.
First off:
It only works with read-only mode of a edit control (as you don't want the text to change often).
I think is specific to Windows Mobile MFC, big windows can handle this a lot better.
The solution is very very hacky.
Solution:
I have a standard CEdit bound to the control.
CEdit m_Message;
DDX_Control(pDX, IDC_MESSAGE,
m_Message);
During the InitDialog and OnSize calls, turn on the display of the scroll bar and setup a timer message.
m_Message.ShowScrollBar(SB_VERT,
TRUE);
SetTimer(DO_ADJUST_DISPLAY_STATE, 50,
0);
In the timer handling code, use the scroll information to determine if the scroll bar needs to be displayed.
If not being displayed, turn off the scroll bar and force the window to redisplay.
void CMessageDlg::OnTimer( UINT_PTR nIDEvent )
{
switch(nIDEvent)
{
case DO_ADJUST_DISPLAY_STATE:
KillTimer(nIDEvent);
// deselect all text
m_Message.SetSel(0, 0);
SCROLLINFO info;
m_Message.GetScrollInfo(SB_VERT, &info);
if(info.nPage > (UINT)info.nMax)
{
// need to re-display the non scroll bar version
m_Message.ShowScrollBar(SB_VERT, FALSE);
// I could not find any other way to force a redisplay
// correctly without display problems...
// first move the window to a know invisible area
// then wait (using a timer) for the window to move
// then move the window back to it's original position
RECT rt;
rt.left = 0;
rt.right = 5;
rt.top = 0;
rt.bottom = 5;
m_Message.MoveWindow(&rt);
SetTimer(DO_REDISPLAY_MESSAGE, 50, 0);
}
break;
case DO_REDISPLAY_MESSAGE:
KillTimer(nIDEvent);
// m_MessagePosition holds the original position
// worked out dynamically during the WM_SIZE
// processing
m_Message.MoveWindow(&m_MessagePosition);
break;
}
}
I hope that helps out other people who may have similar requirements.
I was wondering if I could get in between then and hide the scroll bar if it's not going to be used.
I highly doubt it. But I bet you could call SetScrollInfo some time after the text box is created, and send your own scroll parameters.
EDIT: Wrong link, my bad. Here's the one for the Windows CE

How to remove the border of the client area of a window?

I don't want the border of a window's client area to be seen. Is there any way to remove them? The window is a SDI(Single Document) window.
I also noticed that the border appeares only on the top and left side of the client area (no on the right and bottom). I was very confused.
Thank you very much!
Would something like this be useful in your case ?
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
cs.style = WS_POPUP | WS_VISIBLE; // or others you want
cs.dwExStyle = 0; // or others you want
return CFrameWnd::PreCreateWindow(cs);
}
That involves overloading CWnd::PreCreateWindow in order to modify CREATESTRUCT which defines initialization parameters for a windows.
dwExStyle refers to the extended styles.