Swi*_*ank 3 c++ mfc focus selection cricheditctrl
我有一个带有菜单和 CTabCtrl 的对话框。CTabCtrl 有一个选项卡,其中包含一个 CDialog。反过来,它包含一些静态文本和一个 CRichEditCtrl。窗口获得和失去焦点没有特别的问题。
我自从添加了第二个相同的选项卡,现在每次更改选项卡时,CRichEditCtrl 中的所有文本显然都被选中。它以反转的配色方案显示,如果您按下一个键,所有文本都会被替换。
标志 ECO_NOHIDESEL 的描述说(强调我的):
否定编辑控件的默认行为。默认行为在控件失去输入焦点时隐藏选择,并在控件接收输入焦点时显示选择。如果指定 ECO_NOHIDESEL,则即使控件没有焦点,所选文本也会反转。
“显示选择”对我来说听起来像是“显示此控件上次获得焦点时的任何选择”,这不是正在发生的事情。通常在失去焦点之前没有选择任何内容,但是如果我确实尝试离开选择,请返回另一个选项卡并返回,整个文本像往常一样被选中。
可以阻止这种选择吗?
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();
}
Run Code Online (Sandbox Code Playgroud)
Edit 和 Rich Edit 控件的默认行为是在控件没有输入焦点时使所选内容不可见,而仅在控件具有焦点时才使其可见。然而,选择没有改变。该ES_NOHIDESEL样式会覆盖此默认行为,并使所选内容始终出现在控件中,无论它是否具有焦点。您以前肯定见过这种行为:Microsoft Word 和 Visual Studio 都这样做。
因此,您对 SDK 文档的理解是完全正确的。不幸的是,Rich Edit 控件的行为还有另一个方面的障碍。每当对话框中承载的 Edit 或 Rich Edit 控件获得焦点时,它会自动选择其所有文本,从而消除进程中的当前插入符号位置。该ES_NOHIDESEL不会对这种行为产生任何影响; 它只是在控件未聚焦时更改选择是否可见。您当然可以通过按照IInspectable 建议进行操作并将控件子类化以自定义其WM_GETDLGCODE消息处理来覆盖此全选焦点行为。
但是有一个更简单的解决方案。与 相同ES_NOHIDESEL,您希望ES_SAVESEL在创建时设置控件的样式。尽管您可以ES_NOHIDESEL在资源编辑器中进行设置(“无隐藏选择”),但没有等效的ES_SAVESEL. 您可以手动将其添加到 RC 文件,但不能保证在 Visual Studio 重新生成该文件时它不会被删除。
或者,您可以向 Rich Edit 控件EM_SETOPTIONS发送指定ECO_SAVESEL选项的消息。在 MFC 中,SetOptions成员函数包装了这条消息的发送。例如,在您的OnInitDialog函数中,您可能具有以下内容:
m_myRichEditCtrl.SetOptions(ECOOP_OR, ECO_SAVESEL); // maintain selection across focus events
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2045 次 |
| 最近记录: |