Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
1 / 1 / 1
Регистрация: 07.04.2015
Сообщений: 3
1

Создание акселераторов в runtime посредством CreateAcceleratorTable() или ошибочна ли документация с MSDN

03.01.2018, 22:18. Показов 2964. Ответов 0
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте.

На этом форуме и в интернете уже есть обсуждения похожей проблемы, однако, ни в одном из них не затрагивается суть (как я её вижу), проблемы. Собственно, в чём суть: открыв эту статью, узнаём, что акселератор можно создать двумя способами: используя ресурсы приложения, или непосредственно в runtime, используя структуру ACCEL и функцию CreateAcceleratorTable().

Начнём с первого способа. Используя ResEdit, создаём файл ресурсов со следующим кодом:
C++
1
2
3
4
5
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDR_ACCELERATOR1 ACCELERATORS
{
    "A",            CM_ABOUT, VIRTKEY, CONTROL
}
Затем, загружаем этот акселератор:
C++
1
HACCEL hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1));
После, модифицируем цикл обработки сообщений:
C++
1
2
3
4
5
6
7
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
    if (!TranslateAccelerator(hWnd, hAccel, &msg)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}
И в WndProc ловим WM_COMMAND:
C++
1
2
3
4
5
case WM_COMMAND:
    if (LOWORD(wParam) == CM_ABOUT) {
        MessageBox(hWnd, L"Ctrl+A", L"It's working", NULL);
    }
    break;
После этого, запустив приложение, нажимаем клавиши Ctrl+A и наблюдаем ожидаемый вызов MessageBox'а.

Теперь переходим ко второму способу. Структура ACCEL в указанной статье имеет следующее определение:
C++
1
2
3
4
5
typedef struct tagACCEL { // accl 
    BYTE   fVirt; 
    WORD   key; 
    WORD   cmd; 
} ACCEL;
Создаём экземпляр этой структуры, заполняем, и создаём акселератор:
C++
1
2
3
4
5
ACCEL a;
a.cmd = CM_ABOUT;
a.fVirt = FCONTROL | FVIRTKEY;
a.key = 0x41;
HACCEL  hAccel = CreateAcceleratorTable(&a, 1);
После чего запускаем приложение и с растопыренными глазами смотрим, что при нажатии клавиш Ctrl+A уже ничего не происходит, даже не отсылается WM_COMMAND.

Чудеса? Нет, конечно!
После неудачной попытки создать акселератор в runtime, ищем в заголовочных файлах определение структуры ACCEL:
C++
1
2
3
4
5
6
7
8
9
10
11
typedef struct tagACCEL {
#ifndef _MAC
    BYTE   fVirt;               /* Also called the flags field */
    WORD   key;
    WORD   cmd;
#else
    WORD   fVirt;               /* Also called the flags field */
    WORD   key;
    DWORD  cmd;
#endif
} ACCEL, *LPACCEL;
И находим ещё одно определение этой структуры, о котором на MSDN и слова не сказано, даже в статье об этой структуре. Естественно, второе определение неактивно из-за препроцессорного условия.

Руководствуясь смекалкой, переопределяем структуру ACCEL:
C++
1
2
3
4
5
6
struct MyAccel
{
    WORD   fVirt;               /* Also called the flags field */
    WORD   key;
    DWORD  cmd;
};
Снова заполняем экземпляр структуры и вызываем CreateAcceleratorTable():
C++
1
2
3
4
5
MyAccel a;
a.cmd = CM_ABOUT;
a.fVirt = FCONTROL | FVIRTKEY;
a.key = 0x41;
HACCEL  hAccel = CreateAcceleratorTable((ACCEL*)&a, 1);
Запускаем приложение и уже с чуть менее растопыренными глазами наблюдаем ожидаемое от приложения поведение – вызов MessageBox'a по нажатию Ctrl+A. Говорить могу только за себя. На других компьютерах это приложение не тестировал. И, собственно, вопрос: может ли кто-нибудь прокомментировать моё данное наблюдение и, если необходимо, указать на допущенные мною ошибки, приведшие к такому стечению обстоятельств?

Я использовал Microsoft Visual Studio 2010 Express, OS – Windows 7 Домашняя расширенная, x64.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
03.01.2018, 22:18
Ответы с готовыми решениями:

Документация MSDN
В библиотеках Windows'a нашел интересные статьи по поводу консоли. Есть ли перевод этой...

MSDN и подобная документация
При открытии документации Visual Studio 2010 или MSDN видится множество пространств имен, классов...

Документация MSDN 2010-2014
Здравствуйте! Подскажите, где можно скачать полную документацию MSDN по C/C++ 2010-2014 года? У...

Заменяемость MSDN или Visual.Net
Работаю на vb6 IDE. Help Требует msdn библиотеку. Нигде в городе не могу найти дисков, говорят уже...

0
03.01.2018, 22:18
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
03.01.2018, 22:18
Помогаю со студенческими работами здесь

Операторы в интерфейсе, кто прав, Troelson или MSDN ?
Читаю Troelson-а, у него написано C# interfaces can define operators! читаю MSDN там написано An...

Где можно скачать MSDN или аналогичны русский HELP?
Здраствуйте! У меня эсть два вопроса: 1. Где можно скачать MSDN или аналогичны русский HELP? ...

Можно ли через ардуино по USB посредством кнопки или сенсора включить или выключить монитор компютера?
Можно ли через ардуино по USB при помощи кнопки или сенсора включить или выключить монитор...

Создание бд Postgresql в runtime
Подскажите, как создать программно бд postgresql с помощью компонентов ZEOSLib.

Документация по ИДЕЕ или Эклипсу.
нужны доки по ИДЕЕ или Эклипсу, и вообще на чем остановиться помогите разобраться!!! я к...

Разработка ресурсов меню и акселераторов клавиатуры
Создать приложение с двумя меню. Первое меню позволяет изменить размеры прямоугольника; второе —...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru