Форум: "Потрепаться";
Текущий архив: 2002.11.28;
Скачать: [xml.tar.bz2];
ВнизLPARAM - Этап 1 - Обучение... Найти похожие ветки
← →
PaRL (2002-11-09 13:09) [0]Контрольный вопрос на эту тему - разложить параметр LParam сообщения WM_KEYDOWN на отдельные составляющие:
type
TKeyState = (ksPressed, ksReleased);
var
RepeatCount: word;
ScanCode: byte;
ExtendedKey: boolean;
PreviousKeyState: TKeyState;
Дано: значение LParam (32-битное целое). Временно вспомнить Паскаль и заполнить все 4 указанные переменные. Значения отдельных бит см. в справке API.
Я этого не понял совсем. Объяcните, пожалуйста кто может. Что значит "разложить"? Как "заполнить переменные"?
С ув. PaRL.
← →
TTCustomDelphiMaster (2002-11-09 13:23) [1]Смотрим в MAPI описание lParam
WM_KEYDOWN
nVirtKey = (int) wParam; // virtual-key code
lKeyData = lParam; // key data
Parameters
nVirtKey
Value of wParam. Specifies the virtual-key code of the nonsystem key.
lKeyData
Value of lParam. Specifies the repeat count, scan code, extended-key flag, context code, previous key-state flag, and transition-state flag, as shown in the following table:
Value Description
0-15 Specifies the repeat count. The value is the number of times the keystroke is repeated as a result of the user holding down the key.
16-23 Specifies the scan code. The value depends on the original equipment manufacturer (OEM).
24 Specifies whether the key is an extended key, such as the right-hand ALT and CTRL keys that appear on an enhanced 101- or 102-key keyboard. The value is 1 if it is an extended key; otherwise, it is 0.
25-28 Reserved; do not use.
29 Specifies the context code. The value is always 0 for a WM_KEYDOWN message.
30 Specifies the previous key state. The value is 1 if the key is down before the message is sent, or it is 0 if the key is up.
31 Specifies the transition state. The value is always 0 for a WM_KEYDOWN message.
Находим RepeatCount
RepeatCount := lParam AND $FFFF;
Нужно понять почему AND и почему $FFFF
Остальные параметры заполнить не трудно.
← →
Skyle (2002-11-09 13:24) [2]Если я правильно понимаю MSDN, то :
Specifies the repeat count, scan code, extended-key flag, context code, previous key-state flag, and transition-state flag, as shown in the following table.
0-15
Specifies the repeat count for the current message. The value is the number of times the keystroke is autorepeated as a result of the user holding down the key. If the keystroke is held long enough, multiple messages are sent. However, the repeat count is not cumulative.
16-23
Specifies the scan code. The value depends on the OEM.
24
Specifies whether the key is an extended key, such as the right-hand ALT and CTRL keys that appear on an enhanced 101- or 102-key keyboard. The value is 1 if it is an extended key; otherwise, it is 0.
25-28
Reserved; do not use.
29
Specifies the context code. The value is always 0 for a WM_KEYDOWN message.
30
Specifies the previous key state. The value is 1 if the key is down before the message is sent, or it is zero if the key is up.
31
Specifies the transition state. The value is always zero for a WM_KEYDOWN message.
То есть, сообщение может отправляться когда клавиша уже отпущена, а может и тогда, когда клавиша ещё нажата. Соответственно, данный параметр содержит состояние этой самой клавиши на момент отправки сообщения.
← →
Skyle (2002-11-09 13:26) [3]Ну вот....и так бывает....%)
← →
PaRL (2002-11-09 14:48) [4]
> Нужно понять почему AND и почему $FFFF
Я не понял почему.
Я понимаю все эти операции or, and сложение, вычитание - я разобрался со всей теорией, а это никак.
Почему and и $FFFF.
И что такое $.
И ещё один параметр для примера если можно.
← →
Anatoly Podgoretsky (2002-11-09 15:12) [5]and используется для изоляции битов, в данном случае все биты будут сброшены в 0, кроме битов 0-15, те останутся неизменными, в результате будут выделены repeat count
← →
vuk (2002-11-09 15:19) [6]Чтобы понять, как именно происходит изоляция битов вспомните, как выглядит таблица истинности для логической операции AND (она же логическое умножение), а потом представьте оба числа в двоичном виде и побитово примените к ним эту таблицу истинности.
← →
Anatoly Podgoretsky (2002-11-09 15:30) [7]PaRL © (09.11.02 14:48)
$ - префикс шестнадцатиричной записи
← →
TTCustomDelphiMaster (2002-11-09 15:36) [8]
$FFFF это число 65535 в шестнадцатиричной системе счисления.
В двоичной системе оно выглядит так 11111111 11111111
В результате операции RepeatCount := lParam AND $FFFF получим
lParam XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX
AND
$FFFF 00000000 00000000 11111111 11111111
RepeatCount 00000000 00000000 XXXXXXXX XXXXXXXX
где X - любое состояние бита 0 или 1
Таким образом RepeatCount будет содержать младшие 16 бит lParam, что соответствует числу повторов нажатия клавиши по спецификации.
← →
Anatoly Podgoretsky (2002-11-09 15:50) [9]А что бы проверить, что ты понял, вот тебе домашнее задание, заполнить следующую структуру, на основании определения бит LParam.
var
LParamRec = record
RepeatCount : Integer;
ScanCode : Byte;
ExtendedKey : Boolean;
Reserved : Integer;
ContextCode : Boolean;
KeyDown : Boolean;
TransState : Boolean;
end;
LParam : LongWord;
end;
← →
PaRL (2002-11-09 18:15) [10]Я не знал что 0..15 - это положение битов.
Спасибо.
← →
PaRL (2002-11-09 18:57) [11]
var WndH, ed : HWND;
wc : TWndClassEx;
lp : LParam;
RepeatCount: word;
ScanCode, ex, prev: byte;
function WindowProc(WndH : HWND; Msg : integer; wParam : wParam;
LParam : LParam) : LongInt; stdcall;
begin
Result := 0;
case Msg of
WM_DESTROY: begin
PostQuitMessage(0);
Exit;
end;
WM_KEYDOWN: begin
RepeatCount := lParam and $FFFF; //RepeatCount
lp := Lparam shr 16;
ScanCode := lp and $F; //ScanCode
lp := LParam shr 24;
ex := lp and $1; //ExtendedKey
lp := LParam shr 30;
prev := lp and $1; //KeyState
ShowMessage("RepeatCount = " + IntToStr(RepeatCount) + #13+
"ScanCode = " + IntToStr(ScanCode) + #13 +
"ExtendedKey = " + IntToStr(ex) + #13 +
"PreviousKeyState = " + IntToStr(prev));
end;
else Result := DefWindowProc(WndH, Msg, wParam, LParam);
end;
end;
А что такое ExtendedKey - он всё время 0, я так понял это что-то с типом клавиатуры связано(101, 102 клавиши).
А остальное всё работает вроде как.
И ещё. Можно ли как-то без сдвигов обойтись?
Правильно у меня?
← →
TTCustomDelphiMaster (2002-11-09 19:28) [12]+ RepeatCount: word; // Ну это понятно
- ScanCode: byte; // Почему $F там же 8 бит
- ExtendedKey: boolean; // Логическая переменная, а у вас что? Здесь можно обойтись без сдвигов.
- PreviousKeyState: TKeyState; // Должен быть равен элементу множества TKeyState = (ksPressed, ksReleased); Здесь тоже без сдвигов.
PS: Вроде бы говорили делать все это на бумажке :)
← →
TTCustomDelphiMaster (2002-11-09 20:42) [13]Кстати с RepeatCount тоже переборщили. Достаточно RepeatCount := LParam;, т.к. левая часть этого выражения имеет тип word (2 байта) все лишнее будет отброшено.
← →
PaRL (2002-11-09 21:11) [14]
> - PreviousKeyState: TKeyState; // Должен быть равен элементу
> множества TKeyState = (ksPressed, ksReleased); Здесь тоже
> без сдвигов.
Ну и что. Всё правильно работает. В хелпе написано, что это флаг, означающий, нажата ли клавиша(не помню как именно звучит, но смысл такой) - я проверял - и всё в порядке.
Попробуйте, держите клавишу и нажимайте ОК на всплывающих ShowMessage - если клавиша долго нажата - то будет 1, а если один раз нажали и отпустили - то один. И ExtendedKey тоже также.
Вот только Scan неверно и всё я думаю.
А про типы, так True - 1, False - 0.
Может кто-нибудь ещё скажет по этому поводу?
← →
Anatoly Podgoretsky (2002-11-09 21:29) [15]А не надо закладываться на внутреннее устройство
"А про типы, так True - 1, False - 0."
← →
PaRL (2002-11-10 08:40) [16]Хорошо, напишите пожалуйста всё полностью как должно быть.
Страницы: 1 вся ветка
Форум: "Потрепаться";
Текущий архив: 2002.11.28;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.008 c