Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Visual C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 04.01.2013, 08:18   #1
Tahoma
DI HALT RET
Форумчанин
 
Аватар для Tahoma
 
Регистрация: 30.12.2010
Сообщений: 117
По умолчанию [Вопрос] Сочетание клавиш в RichEdit

Доброе время суток.
Возник такой вопрос: как обработать IDC_SAVE в меню из RichEdit?
Создаю окно и RichEdit в нем:
Код:
	hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
		x, y, x_wnd, y_wnd, NULL, NULL, hInstance, NULL);

	hRE = CreateWindowEx(NULL,
						"RichEdit20A",
						NULL,
						WS_VISIBLE | ES_MULTILINE | WS_CHILD | WS_VSCROLL,
						0, 0, rect.right-rect.left, rect.bottom-rect.top,
						hWnd,
						NULL,
						hInstance,
						NULL);
Меню создано в ресурсах. Также в ресурсах создал акселератор. По нажатию CTRL+S нормально вызывается IDC_SAVE присвоенный пункту меню "Сохранить". Но если фокус установить в рич, то уже не срабатывает.
Пробовал сделать перехват по ENM_KEYEVENTS:
Код:
		case WM_NOTIFY:
		{	
			const MSGFILTER * pF = (MSGFILTER *)lParam;
			if (pF->nmhdr.hwndFrom == hRE)
			{
				if(pF->msg == WM_KEYDOWN)
				{
					sprintf(asd, "\n%X|%X\n", pF->lParam, pF->wParam);
					st.flags = ST_SELECTION;
					st.codepage = CP_ACP;
					SendMessage(hRE, EM_SETTEXTEX, (WPARAM)&st, (LPARAM)asd);

					// обработка нажатия CTRL+S
				}
			}
Выводит в рич содержимое lParam и wParam из MSGFILTER. На CTRL реагирует, на 'S' реагирует. На одновременное нажатие, не реагирует.

Можно ли привязать акселератор и к ричу (да и вообще ко всем дочерним окнам)? А если можно, как? Ну или как обойти?

Заранее спасибо.

p.s.: извиняюсь за ошибку в названии темы

Последний раз редактировалось Tahoma; 04.01.2013 в 08:45.
Tahoma вне форума Ответить с цитированием
Старый 04.01.2013, 08:53   #2
Perchik71
С++, Delphi
Форумчанин
 
Аватар для Perchik71
 
Регистрация: 24.11.2012
Сообщений: 495
По умолчанию

одноврменное нажатие.... если мне память не изменяет можно добица путём создания своего vk_event... попробуйте сложить код буквы и код ctrl.
//----
если заробит, то трабла будет в ином. по поводу аксселератора, он привязывается вобще то отдельным методом.
HACCEL hAcc;
hAcc = LoadAccelerators(hInst, MAKEINTRESOURCE(ID_MENUACC));
Если помог, тут весы есть , Вам не сложно, а мне приятно.

Последний раз редактировалось Perchik71; 04.01.2013 в 09:01.
Perchik71 вне форума Ответить с цитированием
Старый 04.01.2013, 08:55   #3
Tahoma
DI HALT RET
Форумчанин
 
Аватар для Tahoma
 
Регистрация: 30.12.2010
Сообщений: 117
По умолчанию

Цитата:
Сообщение от Perchik71 Посмотреть сообщение
одноврменное нажатие.... если мне память не изменяет можно добица путём создания своего vk_event... попробуйте сложить код буквы и код ctrl.
Не получается. Обработчик замолкает, если две кнопки одновременно нажать. Обрабатывает только по одной.
Tahoma вне форума Ответить с цитированием
Старый 04.01.2013, 09:07   #4
Perchik71
С++, Delphi
Форумчанин
 
Аватар для Perchik71
 
Регистрация: 24.11.2012
Сообщений: 495
По умолчанию

советую вам запрыгнуть сюда, тут всё для работы с клавой.. вплоть до ловушек.
///
забыл..
укажите в цикле сообщений
TranslateAccelerator()
Если помог, тут весы есть , Вам не сложно, а мне приятно.
Perchik71 вне форума Ответить с цитированием
Старый 04.01.2013, 09:13   #5
Tahoma
DI HALT RET
Форумчанин
 
Аватар для Tahoma
 
Регистрация: 30.12.2010
Сообщений: 117
По умолчанию

Цитата:
Сообщение от Perchik71 Посмотреть сообщение
советую вам запрыгнуть сюда, тут всё для работы с клавой.. вплоть до ловушек.
///
забыл..
укажите в цикле сообщений
TranslateAccelerator()
С ссылкой ознакомлюсь, спасибо.
Акселератор указан:
Код:
	while (GetMessage(&msg, NULL, 0, 0))
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}
только вот работает с главным окном, а на дочерние чихать хотел
Tahoma вне форума Ответить с цитированием
Старый 04.01.2013, 09:22   #6
Perchik71
С++, Delphi
Форумчанин
 
Аватар для Perchik71
 
Регистрация: 24.11.2012
Сообщений: 495
По умолчанию

Цитата:
Если происходит нажатие клавиш ускорителя, которое соответствует пункту меню, когда окно - владелец меню, свернуто, TranslateAccelerator не отправляет сообщение WM_COMMAND. Однако, если происходит нажатие клавиш ускорителя, который не соответствует какому - либо из из пунктов в меню окна или системного меню окна, функция отправляет сообщение WM_COMMAND, даже если окно свернуто.
Код:
if ((TranslateAcceleratorW(hMain, hMainTable, uMsg) = 0) and (not IsDialogMessageW(hMain, uMsg))) and
          ((TranslateAcceleratorW(hList, hListTable, uMsg) = 0) and (not IsDialogMessageW(hList, uMsg))) and
          ((TranslateAcceleratorW(hBook, hBookTable, uMsg) = 0) and (not IsDialogMessageW(hBook, uMsg))) then
выдержка с другого форума.... думаю вы уже поняли где ошибка?
у вас должно быть два транслате.
/----
hMainTable - допустим ваш аксселератор... попробуйте его пропускать по двум окнам.
Если помог, тут весы есть , Вам не сложно, а мне приятно.

Последний раз редактировалось Perchik71; 04.01.2013 в 09:26.
Perchik71 вне форума Ответить с цитированием
Старый 04.01.2013, 09:32   #7
Perchik71
С++, Delphi
Форумчанин
 
Аватар для Perchik71
 
Регистрация: 24.11.2012
Сообщений: 495
По умолчанию

Если он опять задолбает, то знай в комманд попадет аксселератор. wparam(старшее слово) равно 1 - значит акселератор, wparam(младшее слово) код акселератора.
Если помог, тут весы есть , Вам не сложно, а мне приятно.
Perchik71 вне форума Ответить с цитированием
Старый 07.01.2013, 17:09   #8
Tahoma
DI HALT RET
Форумчанин
 
Аватар для Tahoma
 
Регистрация: 30.12.2010
Сообщений: 117
По умолчанию

Привязал акселератор на хэндл hRE. Теперь печатает сразу по 2-4 символа, но на CTRL+S все равно не реагирует.
Tahoma вне форума Ответить с цитированием
Старый 08.01.2013, 08:31   #9
Tahoma
DI HALT RET
Форумчанин
 
Аватар для Tahoma
 
Регистрация: 30.12.2010
Сообщений: 117
По умолчанию

Нашел наконец решение через обработку всего рича:
Код:
	WNDPROC			oldREproc;
	//...
	hRE = CreateWindowEx(NULL,
						"RichEdit20A",
						NULL,
						WS_VISIBLE | ES_MULTILINE | WS_CHILD | WS_VSCROLL,
						0, 0, rect.right-rect.left, rect.bottom-rect.top,
						hWnd,
						NULL,
						hInstance,
						NULL);
	oldREproc = (WNDPROC)SetWindowLong(hRE, GWL_WNDPROC,(long)REProc);
	//...
LRESULT REProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	SHORT sh;
	switch(message)
	{
	case WM_KEYUP:
		sh = GetKeyState(VK_CONTROL) & 0x80;
		if (sh == 0x80 && wParam == 0x53)
		{
			SaveAS(true);
			correct = false;
			break;
		}
		break;
	}
	return CallWindowProc(oldREproc, hWnd, message, wParam, lParam);
}
Tahoma вне форума Ответить с цитированием
Старый 08.01.2013, 12:18   #10
Smogg
Участник клуба
 
Регистрация: 14.06.2011
Сообщений: 1,138
По умолчанию

Обработку событий клавы крайне желательно вешать на KEYDOWN, с мышой - ровно наоборот, на KEYUP. Можно и так, как у вас, но это будет смущать многолетние привычки юзера. Ну, вот так повелось от изначально, что символ печатается по нажатию, а не по отпусканию клавиши.

After a while:
Мутная это какая-то тема - акселераторы.
Msdn и вправду настаивает на сабклассинге контрола, имеющего в данный момент фокус...

Последний раз редактировалось Smogg; 08.01.2013 в 13:32.
Smogg вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Сочетание клавиш. Vaigard Общие вопросы Delphi 10 29.12.2010 18:25
Сочетание клавиш Fezdipekla Microsoft Office Access 3 19.06.2010 19:38
Не работает сочетание клавиш vikttur Операционные системы общие вопросы 6 06.06.2010 00:23
Сочетание клавиш Денис546546 Помощь студентам 3 07.12.2009 09:45
Сочетание клавиш Malder Общие вопросы .NET 0 19.01.2009 20:57