void CExtEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
switch (nChar)
{
case VK_TAB:
break;
default: CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
}
}
Отмена перекл. контролов клавишей Tab
диалог вызывается у меня вызовом CreateDialog из ресурсов,
в диалоге есть многострочный TEXT (или RichEdit2),
несколько Static и Button-ов,
суть диалога заключается в редактировании некоего многострочного текста,
и есть одна загвоздка - в том, что в текстовом контроле требуется возможность вводить символ ASCII 9 (клавиша TAB),
но это не получается, т.к по нажатию TAB контрол теряет фокус, перепрыгивая на другой элемент.
попробовал поубирать для всех элементов стиль WS_TABSTOP,
также пробовал вариант когда текстовый контрол создается не из ресурса а через CreateWindowEx,
максимум чего получается, это когда фокус никуда не прыгает но текстовый контрол ведет себя всеравно не так,
вместо втавки символа табуляции и спокойного продолжения редактирования после нажатия TAB, я получаю выделения всего текста!
Как избавиться от такого поведения,
если в данном случае в диалоговом окне мне на*ер не нужна эта фича с переключением табом по контролам?
Народ, снимите с мертвой точки, не пойму куда копать дальше...
1. Наследовать класс от CEdit (напр. CExtEdit)
2. Обрабатывать в нем сообщение WM_KEYDOWN (функция OnKeyDown)
Пример:
Код:
В данном примере в Edit-e ничего не делается при нажатии клавиши TAB
3. Создать переменную типа CExtEdit (наследника от CEdit) связав её с нужным ресурсом на диалоге.
Вроде должно работать (правда пробовалось на модальном диаложке сгенеренном студией :)))
Цивилизованно всё делается через DLGC_WANTTAB.
Цитата: Freeman
Цивилизованно всё делается через DLGC_WANTTAB.
Позволю себе не согласиться.
1. Не DLGC_WANTTAB, а через стиль WS_TABSTOP. DLGC_WANTTAB - напрямую можно, но нежелательно юзать, на него в МСДН толком даже ничего нет, кроме того, как оно взаимодействует со стилем WS_TABSTOP и перемещением по контролам-окнам.
2. Смотри вопрос внимательнее: человеку требуется работать табом в Edit-е, а не игнорировать его когда переключаешься по контролам. А то что ты предлагаешь эквивалентно стилю WS_TABSTOP, что, как я уже сказал ранее не подходит.
Очень хотелось чтоб текстовое поле было из ресурса и минимально к нему дописывать
__AleXX__, у меня кстати FMC не задействован, используется Win32++, в качестве родительского класса для диалога - CDialog
значит как пытался работать с темой DLGC_WANTTAB:
вот такой обработчик
Код:
LRESULT CALLBACK DialogEditProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg)
{
case WM_GETDLGCODE:
//return DLGC_WANTTAB;
return DLGC_WANTALLKEYS;
}
return FALSE;
}
switch (uMsg)
{
case WM_GETDLGCODE:
//return DLGC_WANTTAB;
return DLGC_WANTALLKEYS;
}
return FALSE;
}
там я пробовал по разному с него выходить, факт в том что выполнение ни при каких обстоятельствах туда не доходит,
прицепливание его к контролу
Код:
BOOL CDialog_Editor::OnInitDialog()
{
SetWindowLong( GetDlgItem(m_hWnd, IDC_EDIT1), GCL_WNDPROC, (LONG)DialogEditProc );
...
}
{
SetWindowLong( GetDlgItem(m_hWnd, IDC_EDIT1), GCL_WNDPROC, (LONG)DialogEditProc );
...
}
CDialog_Editor - это класс данного диалога
данный прием не срабатывает
диалог в ресурсе описан след. образом
Код:
IDW_EDITOR DIALOGEX 0,0,392,327
STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SETFONT | DS_FIXEDSYS | WS_VISIBLE | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU
CAPTION "Editor"
FONT 8,"MS Shell Dlg 2",400,0,1
BEGIN
PUSHBUTTON "Save",IDOK,7,306,50,14,NOT WS_TABSTOP
PUSHBUTTON "Cancel",IDCANCEL,335,306,50,14,NOT WS_TABSTOP
LTEXT "Filename:",IDC_STATIC,10,9,29,8
CONTROL "",IDC_STATIC1,WC_STATIC,WS_BORDER | NOT WS_GROUP | SS_LEFTNOWORDWRAP,43,7,342,12
CONTROL "RichEdit2",IDC_EDIT1,RICHEDIT_CLASS,WS_HSCROLL | WS_VSCROLL | WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE | ES_WANTRETURN,8,28,377,270
END
STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SETFONT | DS_FIXEDSYS | WS_VISIBLE | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU
CAPTION "Editor"
FONT 8,"MS Shell Dlg 2",400,0,1
BEGIN
PUSHBUTTON "Save",IDOK,7,306,50,14,NOT WS_TABSTOP
PUSHBUTTON "Cancel",IDCANCEL,335,306,50,14,NOT WS_TABSTOP
LTEXT "Filename:",IDC_STATIC,10,9,29,8
CONTROL "",IDC_STATIC1,WC_STATIC,WS_BORDER | NOT WS_GROUP | SS_LEFTNOWORDWRAP,43,7,342,12
CONTROL "RichEdit2",IDC_EDIT1,RICHEDIT_CLASS,WS_HSCROLL | WS_VSCROLL | WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE | ES_WANTRETURN,8,28,377,270
END
в классе основного окна заюз диалога происходит след образом
Код:
class CMainWindow : public CWnd {
public:
CDialog_Editor m_DialogEditor;
...
}
void CMainWindow::Dialog_Editor(std::string path)
{
m_DialogEditor.setFileName(path);
m_DialogEditor.DoModal();
}
public:
CDialog_Editor m_DialogEditor;
...
}
void CMainWindow::Dialog_Editor(std::string path)
{
m_DialogEditor.setFileName(path);
m_DialogEditor.DoModal();
}
когда нужно приложение дергает Dialog_Editor(...) с нужным файлом для редактирвания
некоторые делати опущены, но тут надеюсь картина понятна
по Win32++ детали тут
http://users.bigpond.net.au/programming/documentation.htm
http://users.bigpond.net.au/programming/tutorial.htm
вобщем красиво сделать не выходит :-/
буду попробовать наследовать диалог от CWnd, создавать текстовый контрол вручную и в WndProc влазить...
Код:
LRESULT CALLBACK DialogEditProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg)
{
case WM_GETDLGCODE:
return DLGC_WANTTAB;
}
return FALSE;
}
switch (uMsg)
{
case WM_GETDLGCODE:
return DLGC_WANTTAB;
}
return FALSE;
}
Таким обработчиком, даже если заходить будет, то ничего не измениться :)) Оно так работает поумолчанию, т.е. с пом. TAB переходит от окна к окну.
Надо у всех контролов на диаложке убрать стиль WS_TABSTOP, либо переопределить обработку RichEdit2-ом нажатие клавиши TAB.
В функции обработки сообщений лови сообщение WM_KEYDOWN, фильтруй на TAB и будет тебе счастье.
какбы есть NOT WS_TABSTOP в ресурсе на всех элементах где токо можно
а в функцию DialogEditProc вообще выполенние не приходит
вставлял в начале TRACE - она не дергается ни при каких событиях
попробовал еще переопределить DialogProc в классе диалога, по идее это обертка оконной функции диалога, ни на WM_GETDLGCODE ни WM_KEYUP ответа не происходит
Мне кажется, что там как в MFC есть возможность как-то обрабатывать сообщения, иначе бы они тебе доходили :).
Короче, удачи в поисках :)
(у меня инет урезанный, пока помочь более ничем не могу)
Цитата: alexnd
попробовал еще переопределить DialogProc в классе диалога, по идее это обертка оконной функции диалога, ни на WM_GETDLGCODE ни WM_KEYUP ответа не происходит
Так реализовано в VCL:
Код:
procedure TCustomMemo.WMGetDlgCode(var Message: TWMGetDlgCode);
begin
inherited;
if FWantTabs then Message.Result := Message.Result or DLGC_WANTTAB
else Message.Result := Message.Result and not DLGC_WANTTAB;
if not FWantReturns then
Message.Result := Message.Result and not DLGC_WANTALLKEYS;
end;
begin
inherited;
if FWantTabs then Message.Result := Message.Result or DLGC_WANTTAB
else Message.Result := Message.Result and not DLGC_WANTTAB;
if not FWantReturns then
Message.Result := Message.Result and not DLGC_WANTALLKEYS;
end;
Код:
m_DialogEditor.DoModeless();