How do i disable copy paste menu in Error Text field when long press (magnifying glass comes up) - cosmicmind

func canPerformAction(action: Selector, withSender sender: AnyObject?) -> Bool {
// Disable copy, select all, paste
if action == #selector(UIResponderStandardEditActions.copy(:)) || action == #selector(UIResponderStandardEditActions.selectAll(:)) || action == #selector(UIResponderStandardEditActions.paste(_:)) {
return false
}
// Default
return super.canPerformAction(action, withSender: sender)
}

Related

Why won't this local enum class / lambda function combination work correctly?

This is a boilerplate OnInitDialog handler for CDialog project. I added a enum class and lambda to it:
BOOL CMFCApplication8Dlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != nullptr)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
enum class EnumStudentItemType
{
BibleReading,
InitialCall,
ReturnVisit,
BibleStudy,
Talk,
Other
};
auto GetStudentItemType = &[](CString strType) -> EnumStudentItemType
{
if (strType == L"Bible Reading")
{
return EnumStudentItemType::BibleReading;
}
if (strType == L"Initial Call")
{
return EnumStudentItemType::InitialCall;
}
if (strType == L"Return Visit")
{
return EnumStudentItemType::ReturnVisit;
}
if (strType == L"Bible Study")
{
return EnumStudentItemType::BibleStudy;
}
if (strType == L"Talk")
{
return EnumStudentItemType::Talk;
}
return EnumStudentItemType::Other;
};
auto eType = GetStudentItemType(L"Bible Reading");
return TRUE; // return TRUE unless you set the focus to a control
}
It does not like this line:
auto eType = GetStudentItemType(L"Bible Reading");
If I move the enum class into the header, and turn the GetStudentItemType method into a function defined in the header, then that line of code which attempts to get the type does not display errors in the IDE.
So:
How do we define a enum class inside a function (not needed anywhere else)? And ...
Use it as a return value for a lambda?

Accelerator keys not working when modeless popup has the focus

My main CDialog sometimes displays a child modeless dialog like this:
It is only displayed if the user has configured it to automatically display.
It gets displayed via the main dialogs OnInitDialog where this function is called:
void CChristianLifeMinistryEditorDlg::DisplayAssignHistoryDialog()
{
BOOL bShowAssignHistoryDialog;
bShowAssignHistoryDialog = theApp.GetNumberSetting(_T("Options"), _T("SM_ShowAssignHist"), TRUE);
if (bShowAssignHistoryDialog)
{
m_pAssignHistoryDlg = std::make_unique<CAssignHistoryDlg>(); // .release();
if (m_pAssignHistoryDlg != nullptr)
{
m_pAssignHistoryDlg->SetAssignHistMap(&m_mapSPtrHist, &m_HistoryOriginal);
m_pAssignHistoryDlg->Create(IDD_DIALOG_ASSIGN_HISTORY, this);
m_pAssignHistoryDlg->ShowWindow(SW_SHOWNORMAL);
m_pAssignHistoryDlg->UpdateWindow();
m_pAssignHistoryDlg->EnableTree(false);
}
}
}
WhatI have noticed is that some of my main windows ACCELERATOR hotkey keys don't always work. I then realised that this is because the popup window has the focus. If i single click anywhere on the main dialog to give it focus, then my accelerator hotkeys function.
Is there any way that we can easily still allow the main editor to process it's hotkeys even though the modeless window might have focus? A standard way to cater for this?
The main window handles the accelerators like this:
BOOL CChristianLifeMinistryEditorDlg::PreTranslateMessage(MSG * pMsg)
{
if (m_hAccelTable)
{
if (::TranslateAccelerator(GetSafeHwnd(), m_hAccelTable, pMsg))
return TRUE;
}
}
And the popup modeless window also makes use of PreTranslateMessage (incase it is relevant):
BOOL CAssignHistoryDlg::PreTranslateMessage(MSG* pMsg)
{
BOOL bNoDispatch{}, bDealtWith = bDealtWith = FALSE ;
if ( (pMsg->message == WM_KEYDOWN || pMsg->message == WM_KEYUP ||
pMsg->message == WM_CHAR)
&& pMsg->wParam == VK_RETURN)
{
// Eat it.
bNoDispatch = TRUE ;
bDealtWith = TRUE ;
}
if (!bDealtWith)
bNoDispatch = CResizingDialog::PreTranslateMessage(pMsg);
return bNoDispatch ;
}
I would pass your m_hAccelTable from CChristianLifeMinistryEditorDlg to CAssignHistoryDlg and add this to the beginning of CAssignHistoryDlg::PreTranslateMessage:
if (m_hAccelTable)
{
if (::TranslateAccelerator(GetParent()->GetSafeHwnd(), m_hAccelTable, pMsg))
return TRUE;
}

UWP: How to override Ctrl-X, Ctrl-V, etc. in a textbox

I have a text box in my app. In this app, I am creating my own Undo/Redo functionality because the text in my textbox represents something much larger in memory, and I need to track these textbox changes to be able to undo/redo the whole project properly.
As part of that, I need to capture -- and handle -- many common keyboard scenarios on my own. Yes, I know this is going to be painful.
My major hurdle at the moment is the fact that the textbox intercepts (and even hides) the "usual" keys like Ctrl+X, Ctrl+V, Ctrl+Z and Ctrl+Y. It does this so that it can implement its own undo-redo, but I don't need the built-in undo/redo stuff. I would like to completely disable these keys in my UWP app.
I know that you can do this in winforms, but UWP appears to be a different beast.
private async void MyTextBox_KeyDown(object sender, KeyRoutedEventArgs e)
{
var ctrl = Window.Current.CoreWindow.GetKeyState(VirtualKey.Control).HasFlag(CoreVirtualKeyStates.Down);
// Handle special keys!!
if (ctrl && e.Key == Windows.System.VirtualKey.F)
{
Find_Click(null, null);
e.Handled = true;
}
else if (ctrl && e.Key == Windows.System.VirtualKey.R)
{
Replace_Click(null, null);
e.Handled = true;
}
...
else if (ctrl && e.Key == Windows.System.VirtualKey.Z)
{
// THIS DOES NOT FIRE
Undo();
e.Handled = true;
}
else if (ctrl && e.Key == Windows.System.VirtualKey.Y)
{
// THIS DOES NOT FIRE
Redo();
e.Handled = true;
}
else if (ctrl && e.Key == Windows.System.VirtualKey.X)
{
// THIS DOES NOT FIRE
CaptureUndo("");
e.Handled = true;
}
else if (ctrl && e.Key == Windows.System.VirtualKey.V)
{
// THIS FIRES, BUT THE PASTE HAS ALREADY HAPPENED
// SO e.Handled IS USELESS
string s=GetClipboardText();
CaptureUndo(s);
e.Handled = true;
}
}
I would really appreciate a nudge in the right direction.

CTreeCtrl: How to clear the focus of selected item

Am new to MFC, I want to replicate the exact Ctrl+Page Down and Ctrl+Page Up behavior to regular Page Down/Page Up keys without any supporting keys (Ctrl/Shift). I have been trying to clear the focus of item which is getting selected automatically on striking the keys Page Up and Page Down.
I've tried with this code but its not working:
case VK_NEXT: // pagedown
case VK_PRIOR: // pageup
lhItem = GetFocusedItem();
if (IsSelected(lhItem))
{
CTreeCtrl::SetItemState(lhItem, 0, TVIS_SELECTED);
}
break;
Can anyone please help me in solving it
The Code need to written in OnSelChanging & OnSelChanged Event Handler functions
void CTreeCtrl::OnSelchanging(NMHDR *pNMHDR, LRESULT *pResult)
{
HTREEITEM hNew = pNMTreeView->itemNew.hItem;
HTREEITEM hOld = pNMTreeView->itemOld.hItem;
m_bOldItemSelected = hOld && (CTreeCtrl::GetItemState(hOld, UINT(TVIS_SELECTED)) & TVIS_SELECTED);
if (GetSelectedCount() > 1)
{
if (m_bPgUpState || m_bPgDownState)
{
//Check the state of New Item
if ((pNMTreeView->itemNew.state & TVIS_SELECTED))
{
// If the item is selected, so make sure OnSelchanged()
// will "select" it !
m_bNewItemSelected = TRUE;
}
else if (!(pNMTreeView->itemNew.state & TVIS_SELECTED))
{
// The New item is not selected, so make sure OnSelchanged()
// will not "re-select" it !
m_bNewItemSelected = FALSE;
CTreeCtrl::SetItemState(hNew, UINT(~TVIS_SELECTED), UINT(TVIS_SELECTED));
}
}
}
void TreeCtrl::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
HTREEITEM itemNew = pNMTreeView->itemNew.hItem;
HTREEITEM itemOld = pNMTreeView->itemOld.hItem;
if ((m_bPgUpState || m_bPgDownState) && (GetSelectedCount() > 1)
&& (pNMTreeView->itemOld.hItem != NULL || pNMTreeView->itemNew.hItem != NULL))
{
// It had the focus so Keep selection at old item
if (itemOld && m_bOldItemSelected)
{
CTreeCtrl::SetItemState(itemOld, UINT(TVIS_SELECTED), UINT(TVIS_SELECTED));
m_bOldItemSelected = FALSE;
}
else
{
// Do-not select the item if it is not selected
CTreeCtrl::SetItemState(itemOld, UINT(~TVIS_SELECTED), UINT(TVIS_SELECTED));
}
}
In this article you'll find solution for every thing about CTreeCtrl
Full-Featured Tree Control

Detect when dialog sets focus to various combo controls using PreTranslateMessage

I have a CDialog and I am trying to override PreTranslateMessage like this:
BOOL CWeekendMeetingDlg::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_SETFOCUS)
{
if (::GetDlgCtrlID(pMsg->hwnd) != IDC_COMBO_PT_CHAIRMAN &&
::GetDlgCtrlID(pMsg->hwnd) != IDC_COMBO_PT_OPEN_PRAYER &&
::GetDlgCtrlID(pMsg->hwnd) != IDC_COMBO_WT_CLOSE_PRAYER &&
::GetDlgCtrlID(pMsg->hwnd) != IDC_COMBO_WEEKEND_HOST &&
::GetDlgCtrlID(pMsg->hwnd) != IDC_COMBO_WEEKEND_COHOST &&
::GetDlgCtrlID(pMsg->hwnd) != IDC_COMBO_PT_READER)
{
if (m_gridAssignHist.GetRowCount() != 1)
{
m_gridAssignHist.SetRowCount(1);
}
}
}
return CDialog::PreTranslateMessage(pMsg);
}
It is not working. What I want to do is reset my CGridCtrl row count to 1 when other controls gain focus (eg: edit combo). But if I put a breakpoint inside the first if it is never intercepted.
At the moment the only thing I can think of is to renumber all of the combo IDs on the dialog so they are sequential and then use a command range for OnSetFocus and detect in that handler. But there are also some CEdit controls.
Can't I use PTM though and avoid that? For me it seems it would be the easiest.
Here is the dialog:
At the moment I have 7 combo OnSetFocus handlers. When they fire the display specific assignment history in the grid on the right.
So if the user moves to any other control on the dialog, the assignment history control will not apply. And that was why i wanted to reset the history to just the header row. And I was hoping to do this with PTM.
Child control notifications are received in the parent dialog via WM_COMMAND messages. Overriding MFC dialog's OnCommand catches those notifications (CBN_SETFOCUS, EN_SETFOCUS etc).
void DoSomething()
{ /* ... */ }
BOOL CWeekendMeetingDlg::OnCommand(WPARAM wParam, LPARAM /*unused*/)
{
switch (HIWORD(wParam))
{
case CBN_SETFOCUS:
switch (LOWORD(wParam))
{
case IDC_COMBO_PT_CHAIRMAN:
// ...more combobox IDCs
DoSomething();
break; // or return TRUE to bypass any message map handlers
}
break;
case EN_SETFOCUS:
switch (LOWORD(wParam))
{
case IDC_EDIT_WHATEVER:
// ...more editbox IDCs
DoSomething();
break;
}
break;
// ...more notification codes
}
return CDialog::OnCommand(wParam, lParam);
}
I have added a 2 second timer to the dialog:
void CWeekendMeetingDlg::OnTimer(UINT_PTR nIDEvent)
{
if (nIDEvent == 1)
{
CWnd* pControl = GetFocus();
if (pControl != nullptr)
{
CWnd* pParent = pControl->GetParent();
if (pParent != nullptr)
{
int iCtrlID = pParent->GetDlgCtrlID();
if (iCtrlID != IDC_COMBO_PT_CHAIRMAN &&
iCtrlID != IDC_COMBO_PT_OPEN_PRAYER &&
iCtrlID != IDC_COMBO_WT_CLOSE_PRAYER &&
iCtrlID != IDC_COMBO_WEEKEND_HOST &&
iCtrlID != IDC_COMBO_WEEKEND_COHOST &&
iCtrlID != IDC_COMBO_PT_READER)
{
if (m_gridAssignHist.GetRowCount() != 1)
{
m_gridAssignHist.SetRowCount(1);
UpdateData(TRUE);
m_strAssignHistLabel = _T("Assignment:");
UpdateData(FALSE);
}
}
}
}
}
CDialog::OnTimer(nIDEvent);
}
This seems to work fine.

Resources