I had a dialog with a menu and a CTabCtrl. The CTabCtrl had one tab, which contained a CDialog. In turn, that contained a few static texts and a CRichEditCtrl. There was no particular issue with the window gaining and losing focus.
I since added a second identical tab, and now every time the tab is changed, all text in the CRichEditCtrl is apparently selected. It is shown in an inverted color scheme and all text is replaced should you hit a key.
The description of flag ECO_NOHIDESEL, says (emphasis mine):
Negates the default behavior for an edit control. The default behavior hides the selection when the control loses the input focus and shows the selection when the control receives the input focus. If you specify ECO_NOHIDESEL, the selected text is inverted, even if the control does not have the focus.
"shows the selection" to me sounds like "show whatever the selection was the last time this control had the focus," which is not what's happening. Normally nothing is selected before focus is lost, but if I do try to leave a selection, go back to the other tab and return, the entire text, as usual, is selected.
Can this selection be prevented?
void EditorDialog::OnTabSelChange( NMHDR * phdr, LRESULT* pResult ) {
CTabCtrl* ptab = (CTabCtrl*) GetDlgItem( IDC_TAB );
int iPageActive = ptab->GetCurSel();
if ( iPageActive >= appage.N() ) {
AKS( AKSWarn, "got tab change to tab %d when I only have %d ppages", iPageActive, appage.N() );
return;
}
ppageActive = appage[ iPageActive ];
SetActivePagePos();
SCWinUtilSetWindowTextVA( this, "Editor: %s", ppageActive->pszFileName );
}
void EditorDialog::SetActivePagePos() {
// STEP 1: Make the proper tab page visible.
for ( int i = 0; i < appage.N(); i++ )
appage[i]->ShowWindow( SW_HIDE );
ppageActive->ShowWindow( SW_SHOW );
// STEP 2: Make the new tab page the right size and position.
CTabCtrl* ptab = (CTabCtrl*) GetDlgItem( IDC_TAB );
CRect rectTab, rectItem;
ptab->GetClientRect( &rectTab );
ptab->GetItemRect( 0, &rectItem );
int iPageX = rectItem.left + 2;
int iPageY = rectItem.bottom + 4;
int iPageW = rectTab.right - 2 - iPageX;
int iPageH = rectTab.bottom - 2 - iPageY;
ppageActive->SetWindowPos( &wndTop, iPageX, iPageY, iPageW, iPageH, SWP_SHOWWINDOW | SWP_NOZORDER );
// STEP 3: Give the window focus and let it know to redraw.
ppageActive->SetFocus();
// When the tab changes the entire content of the RichEdit is selected for some reason.
// As a workaround I manually clear the selection.
CRichEditCtrl* prich = (CRichEditCtrl*) ppageActive->GetDlgItem( IDC_PATCH );
prich->SetSel(-1,-1);
// Redrawing just the prich, or the ppageActive, or the ptab, doesn't
// cause the RichEdit to redraw correctly, but Redrawing the entire dialog does.
RedrawWindow();
}