MFC C++ - MDI tabbed views drop-list menu disappeared - c++

I am learning MFC C++ and found a problem with MDI tabbed menu. Even my application is a MDI style but I can not see document list drop-list menu. Please help me! Thanks in advance!
I have tried to change values in CMDITabInfo but nothing happens...
CMDITabInfo mdiTabParams;
mdiTabParams.m_style = CMFCTabCtrl::STYLE_3D_ONENOTE; // other styles available...
mdiTabParams.m_bActiveTabCloseButton = TRUE; // set to FALSE to place close button at right of tab area
mdiTabParams.m_bTabIcons = FALSE; // set to TRUE to enable document icons on MDI taba
mdiTabParams.m_bAutoColor = TRUE; // set to FALSE to disable auto-coloring of MDI tabs
mdiTabParams.m_bDocumentMenu = TRUE; // enable the document menu at the right edge of the tab area
EnableMDITabbedGroups(TRUE, mdiTabParams);

On ending of your CMainFrame::OnCreate you can write:
EnableMDITabs(TRUE, TRUE, CMFCBaseTabCtrl::LOCATION_TOP, TRUE,
CMFCTabCtrl::STYLE_3D_SCROLLED, FALSE,
FALSE);
CMFCTabCtrl& MFCTabCtrl = GetMDITabs();
MFCTabCtrl.EnableTabSwap(TRUE);
MFCTabCtrl.EnableTabDocumentsMenu(TRUE);
MFCTabCtrl.EnableAutoColor(FALSE);
This ensure you what you need.

Related

Opening a closed application from the dock after pressing X button in Kotlin Multiplatform

Hi for some reason I can't find this answer anywhere.
I can't reopen my application when I close it using the application dock, I can only reopen using the tray to set isOpen back to true.
Code in question:
Tray(
icon = TrayIcon,
menu = {
Item(
"Exit",
onClick = { exitApplication() }
)
Item(
"Open",
onClick = {isOpen.value = true}
)
}
)
if(isOpen.value) {
Window(
onCloseRequest = { isOpen.value = false },
title = "Teamcity Desktop",
state = rememberWindowState(width = 800.dp, height = 900.dp)
) {}
After pressing the X button on my application the window for it disappears (naturally). However the odd part is that I cannot find the way to make it reappear when you click the application icon in the application dock on mac os. The only way to make it reappear is to go to the tray and use the "Open" item. Does anyone know how I would listen for or use a application dock click to reopen the app?
Maybe I need to change my "onCloseRequest" strategy completely?

QGraphicsScene, QTextEdit and lost focus

QTextEdit and similar widgets embedded in QGraphicsScene lose focus after using standard context menu (copy/paste), i. e. you need to click on QTextEdit again to continue editing. Scene emits focusItemChanged with newFocusItem==0.
First question: Is it a bug or standard behavior?
My investigation shows that function QGraphicsItemPrivate::setVisibleHelper() clears focus here:
if (hasFocus && scene) {
// Hiding the focus item or the closest non-panel ancestor of the focus item
QGraphicsItem *focusItem = scene->focusItem();
bool clear = true;
if (isWidget && !focusItem->isPanel()) {
do {
if (focusItem == q_ptr) {
clear = !static_cast<QGraphicsWidget *>(q_ptr)->focusNextPrevChild(true);
break;
}
} while ((focusItem = focusItem->parentWidget()) && !focusItem->isPanel());
}
if (clear)
clearFocusHelper(/* giveFocusToParent = */ false, hiddenByPanel);
}
QGraphisItem has undocumented (internal) flag QGraphicsItem::ItemIsFocusScope. If the flag is set for QTextEdit's proxy-item it gets focus back after menu, but in any case focus cleared at first and after that Item receives it again or not.
Second Question: What is flag QGraphicsItem::ItemIsFocusScope for?
Looks like QGraphicsItem::ItemIsFocusScope is for FocusScope QML item. QtQuick1 is QGraphicsScene based and used that flag.
I'm not sure about side effects but that helps:
auto edit = new QLineEdit();
auto item = scene->addWidget(edit);
item->setFlag(QGraphicsItem::GraphicsItemFlag::ItemIsPanel);
Tested on Qt 5.9, Linux
EDIT
For me looks as bug:
add QLineEdit to scene
click to focus QLineEdit
hit ContextMenu key to show context menu
hit Esc key to exit context menu
try to type
Expected: QLineEdit is focused and text appears
Actual: QLineEdit lost input focus
Please find it or report with Qt bug tracker
So it's OK to have workaround using QGraphicsItem::ItemIsFocusScope flag for example.
#if (QT_VERSION < QT_VERSION_CHECK(<fixed in Qt version>))
// it's workaround of bug QTBUG-...
# if (QT_VERSION == QT_VERSION_CHECK(<version you are develop with>)
item.setFlag(QGraphicsItem::ItemIsFocusScope);
# else
# error("The workaround is not tested on this version of Qt. Please run tests/bug_..._workaround_test")
# endif

MFC tooltips only show up on special occasions

I have been tasked with assigning tooltips to each item in a configuration menu. I have completed "adding" the tooltip to each control on the page, but it seems sometimes the tooltip shows up and sometimes it does not, depending on the position of the control on the screen.
To tooltip-erize the pages I first
EnableToolTips(TRUE);
In each CPropertyPage's OnInitDialog method.
I then add the notification map
ON_NOTIFY_EX(TTN_NEEDTEXT, 0, OnToolTipText)
With the function OnToolTipText looking as such
BOOL CCfgPrefPage::OnToolTipText( UINT id, NMHDR * pNMHDR, LRESULT * pResult )
{
TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR;
UINT nID = pNMHDR->idFrom;
if (pTTT->uFlags & TTF_IDISHWND)
{
nID = ::GetDlgCtrlID((HWND)nID);
if(nID)
{
if( nID == GetDlgItem(IDC_PICKDIST_EDIT)->GetDlgCtrlID())
_tcsncpy_s(pTTT->szText, _T("Tool Tip Text"), _TRUNCATE);
else if( nID == GetDlgItem(IDC_ENDPTTOL_EDIT)->GetDlgCtrlID())
_tcsncpy_s(pTTT->szText, _T("Tool Tip Text"), _TRUNCATE);
pTTT->lpszText = pTTT->szText; // Sanity Check
pTTT->hinst = AfxGetResourceHandle(); // Don't think this is needed at all
return TRUE;
}
}
return FALSE;
}
It seems for some of my controls the tool tip will not show up. For most of the check box controls the tool tip displays, but for a few they just do not show. There are no other controls covering them up, they are not disabled.
Another thing, if I use the non-standard cursor windows repeatedly flashes the tool tip, so much so it is unreadable in some cases. How can I fix this? This is not a problem on CEdit controls, so why is it a problem elsewhere?
EDIT: Update, the controls that have been on the pages for years seem to show tool tips. Any control that I try to add now/today will not show tool tips at all. No matter the position, control type, settings, I cannot get a single tool tip to show on a newly inserted control.
If you do not want to use helper class I have proposed then fix the problems in your code.
First, use ON_NOTIFY_EX_RANGE macro when mapping the even handler, like this (this will cover all IDs):
ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText)
Next, you need to fix your function. I see a few problems here. First, when testing for TTF_IDISHWND flag you only need to re-initalise the nID. You do not need to apply this to the whole function. Second, after all manipulations, your nID will be the actual dialog ID. There is no need to GetDlgItem() function
BOOL CCfgPrefPage::OnToolTipText( UINT id, NMHDR * pNMHDR, LRESULT * pResult )
{
TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR;
UINT nID = pNMHDR->idFrom;
if (pTTT->uFlags & TTF_IDISHWND)
{
nID = ::GetDlgCtrlID((HWND)nID);
}
if(nID)
{
if( nID == IDC_PICKDIST_EDIT)
_tcsncpy_s(pTTT->szText, _T("Tool Tip Text"), _TRUNCATE);
else if( nID == IDC_ENDPTTOL_EDIT)
_tcsncpy_s(pTTT->szText, _T("Tool Tip Text"), _TRUNCATE);
//pTTT->lpszText = pTTT->szText; // Sanity Check
*pResult = 0;
return TRUE;
}
return FALSE;
}
Working with a toolbar which repeats some menu items from menus of an older MFC application, I have worked on this issue of tool tips as well as (1) modifying the toolbar bit map to include additional icons and (2) providing user feedback on current application state. My problem is that I have to do most of this by hand rather than using the various wizards and tools.
What I have done is to (1) add new members to the CView derived class to handle additional messages, (2) modified the toolbar bit map to add in the additional icons using both MS Paint and the Resource Editor, and (3) added new event ids and event handlers to the message map for the CView derived class.
One problem I ran into with the toolbar bitmap change was that since I was inserting an icon, I had to shift an existing icon in the bitmap to the right. My first attempt at this resulted in the shifted icon showing as a blank on the application toolbar. Then I realized that I needed to add a bit more to the length of the toolbar bitmap. After adding a couple more columns to the last icon in the toolbar bitmap to make it a standard width in pixels, the icon displayed properly.
For tooltips I added the following to the message map:
ON_NOTIFY_EX(TTN_NEEDTEXT, 0, OnToolTipText)
I then added the following method to my class to handle the notifications for my menu items. As a side note, it appears that OnToolTipText() is the standard method used in CFrameWnd class and CMDIChildWnd class however CView derives from CWnd as does CFrameWnd so I doubt it makes a difference as to what the method is named.
inline BOOL CPCSampleView::OnToolTipText( UINT id, NMHDR * pNMHDR, LRESULT * pResult )
{
static wchar_t toolTextToggleExportSylk [64] = L"Toggle SYLK export.";
static wchar_t toolTextClearWindow [64] = L"Clear the log displayed.";
static wchar_t toolTextConnectLan [64] = L"Log on the POS terminal through the LAN.";
TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR;
switch (pNMHDR->idFrom) {
case ID_TOGGLE_SYLK_EXPORT:
pTTT->lpszText = toolTextToggleExportSylk;
return TRUE;
case ID_WINDOW_CLEAR:
pTTT->lpszText = toolTextClearWindow;
return TRUE;
case ID_CONNECT_LAN_ON:
pTTT->lpszText = toolTextConnectLan;
return TRUE;
}
// if we do not handle the message then return FALSE to let someone else do it.
return FALSE;
}
For the user feedback on a menu item which toggles a file export when doing reports I provided the following changes to the message map and then implemented the necessary methods. There are two types of messages involved so I had to add two methods and two new message map entries:
// New message map entries to handle the menu item selection event
// and to update the menu item and the toolbar icon with state changes
ON_COMMAND(ID_TOGGLE_SYLK_EXPORT, OnToggleExportSylk)
ON_UPDATE_COMMAND_UI(ID_TOGGLE_SYLK_EXPORT, OnUpdateToggleExportSylk)
// New methods added to the CView derived class
// handle the menu selection event generated by either selecting the menu item
// from the menu or by clicking on the icon in the toolbar.
void CPCSampleView::OnToggleExportSylk()
{
// Exclusive Or to toggle the indicator bit from 0 to 1 and 1 to 0.
GetDocument()->ulReportOptionsMap ^= CPCSampleDoc::ulReportOptionsExportSylk;
}
// handle the request from the MFC framework to update the displayed state this
// not only does a check mark against the menu item it also causes the toolbar
// icon to appear depressed if click is set or non-depressed if click is not set
inline void CPCSampleView::OnUpdateToggleExportSylk (CCmdUI* pCmdUI)
{
if (GetDocument()->ulReportOptionsMap & CPCSampleDoc::ulReportOptionsExportSylk)
{
// SYLK export is turned on so indicate status to the user. This will
// put a check mark beside the menu item and show the toolbar button depressed
pCmdUI->SetCheck (1);
}
else
{
// SYLK export is turned off so indicate status to the user. This will
// remove the check mark beside the menu item and show the toolbar button as raised.
pCmdUI->SetCheck (0);
}
}
The resource file changes were needed to provide a new button for the toggle action as well as to add a new menu item for the toggle action. I am using the same resource id for several different things since these are all separate. So the id for the resource string is the same as for the menu item and is same for the toolbar button so as to simplify my life and make it easy to find all the particular bits and pieces.
The toolbar resource file definition looks like:
IDR_MAINFRAME TOOLBAR 16, 15
BEGIN
BUTTON ID_CONNECT_LAN_ON
SEPARATOR
BUTTON ID_WINDOW_CLEAR
SEPARATOR
BUTTON ID_TOGGLE_SYLK_EXPORT
SEPARATOR
BUTTON ID_APP_ABOUT
END
And the specific part of the menu, which uses the same resource id for the toggle event id looks like:
MENUITEM "Export to SYLK file", ID_TOGGLE_SYLK_EXPORT
Then to provide the status bar text which shows up with a mouse over there is a string table addition:
ID_TOGGLE_SYLK_EXPORT "Toggle export of SYLK format report files for spreadsheets."
The lpszText member of the struct is describe in the MSDN documentation for the TOOLINFO struct as:
Pointer to the buffer that contains the text for the tool, or
identifier of the string resource that contains the text. This member
is sometimes used to return values. If you need to examine the
returned value, must point to a valid buffer of sufficient size.
Otherwise, it can be set to NULL. If lpszText is set to
LPSTR_TEXTCALLBACK, the control sends the TTN_GETDISPINFO notification
code to the owner window to retrieve the text.
Reviewing the existing answer to this question, I wondered about the if statement check for the TTF_IDISHWND flag. The MSDN documentation for the TOOLINFO struct has this to say:
Indicates that the uId member is the window handle to the tool. If
this flag is not set, uId is the tool's identifier.

How to resize context menu displayed with TrackPopupMenu?

I display a context menu from a C++ code using TrackPopupMenu API. Each menu item contains a bitmap 24x24 pixels in size. Added by calling:
MENUITEMINFO mii = {0};
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_BITMAP;
mii.hbmpItem = hBmpForItem;
SetMenuItemInfo(hMenu, ID_1_MENUITEMID, FALSE, &mii);
This works just fine on Windows Vista/7, but on Windows XP some menu items with a longer text get cut off on the right. So, I was wondering, is there any way to increase the width of the menu itself before it's displayed?
Create your menu items as owner-drawn, then have your menu owner window process the WM_MEASUREITEM message so you can specify appropriate widths as needed.

How to split a Window dynamically in MFC without using CSplitterWnd::Create

I create a MFC MDI application, and want to split a window into two parts at a time dynamically by right click and choosing a "AddSplitWnd" pop menu item. I try to use CSplitterWnd::CreateStatic to implement it, once the window is split, it need to create a new view, but I want to use the previous view instead, so does anyone know how to implement it. Thank you.
Here is a code snippet to exchange views in a splitter in a SDI environment. This should be adaptable to work in MDI as well.
CView* CDoc::SwitchToView(CView* pNewView)
{
CFrameWndEx* pMainWnd = (CFrameWndEx*)AfxGetMainWnd();
CView* pOldActiveView;
pOldActiveView = pMainWnd->GetActiveView();
CSplitterWnd* pSplitter = (CSplitterWnd *)pOldActiveView->GetParent();
// in this case Pane 0,0 is exchanged
pOldActiveView = (CView*) pSplitter->GetPane(0,0);
// set flag so that document will not be deleted when view is destroyed
m_bAutoDelete = FALSE;
// Dettach existing view
RemoveView(pOldActiveView);
// set flag back to default
m_bAutoDelete = TRUE;
// Set the child window ID of the active view to the ID of the corresponding
// pane. Set the child ID of the previously active view to some other ID.
::SetWindowLong(pOldActiveView->m_hWnd, GWL_ID, 0);
::SetWindowLong(pNewView->m_hWnd, GWL_ID, pSplitter->IdFromRowCol(0,0));
// Show the newly active view and hide the inactive view.
pNewView->ShowWindow(SW_SHOW);
pOldActiveView->ShowWindow(SW_HIDE);
// Attach new view
AddView(pNewView);
// Set active
pSplitter->GetParentFrame()->SetActiveView(pNewView);
pSplitter->RecalcLayout();
return pOldActiveView;
}
HTH