Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 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
1-92982
Gayrus
2002-11-11 03:03
2002.11.28
KeyToStr


1-93106
VJar
2002-11-17 13:51
2002.11.28
Помогите создать типизованый файл


6-93165
Slice
2002-10-03 13:35
2002.11.28
Как соксифицировать свою программу?


3-92878
SerVS
2002-11-10 00:57
2002.11.28
Выбрать записи в диапозене дат


3-92914
4x4
2002-11-11 14:20
2002.11.28
TQuery и Access???





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский