马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
以下内容泉源于网络,都是有质量的笔墨,如有贰言请告知。
var
wordValue: Word;
highByte, lowByte: Byte;
begin
wordValue := $ABCD; // 示例Word值
highByte := Hi(wordValue); // 取高字节
lowByte := Lo(wordValue); // 取低字节
// 表现效果
ShowMessage('高字节: ' + IntToStr(highByte));
ShowMessage('低字节: ' + IntToStr(lowByte));
// 合成Word
wordValue := (highByte shl 8) or lowByte; // 高字节左移8位,低字节无需变更
// 表现效果
ShowMessage('合成后的Word: ' + IntToHex(wordValue, 4));
end;
//WORD 的高低位互换
function WordLoHiExchange(w: Word): Word; register;
asm
XCHG AL, AH
end;
取高低位的函数: Hi,Lo
取32位中的高低16位:HiWord,LoWord
TMessage 消息布局
PMessage = ^TMessage;
TMessage =packedrecord
Msg: Cardinal;
case Integer of
0: ( WParam: WPARAM; LParam: LPARAM; Result: LRESULT);
1: ( WParamLo: Word; WParamHi: Word; LParamLo: Word; LParamHi: Word; ResultLo: Word; ResultHi: Word);
end;
消息界说
procedure MyMsg(var Msg: TMessage); message WM_USER + 1000;//用户消息上加
begin
case Msg.WParam of
end;
if (Msg.LParam mod 2)=0 then
begin
end;
end;
消息发送
function SendMessage( hWnd: HWND;Msg: UINT;wParam: WPARAM;lParam: LPARAM): LRESULT;stdcall;
//目的窗口句柄 界说的消息编码 参数一 参数二 返回值
function PostMessage( hWnd: HWND;Msg: UINT;wParam: WPARAM;lParam: LPARAM): BOOL;stdcall;
//返回值表现:是否发送乐成
SendMessage(Self.Handle, WM_USER + 1000,1,10);// 发送消息后会期待处置惩罚效果
PostMessage(Self.Handle, WM_USER + 1000,1,10);//把消息送入消息队列.不期待效果
本话题会涉及到: Lo、Hi、HiByte、LoWord、HiWord、MakeWord、MakeLong、Int64Rec
譬如有一个 Cardinal 范例的整数: 1144201745
其十六进制的表现是: $44332211
其二进制表现是: 01000100 00110011 00100010 00010001
我们说 Cardinal 是 32 位的整数, 这里的位是指 "二进制的位数", 不信你数数.
我们须要重点面临的是十六进制, 不管是几进制的数在编译成汇编代码时都是用十六进制表现, 由于它最直观;
我们用十六进制来分析, 也是由于它的直观.
怎么直观的? Cardinal 有 32 位, 每 8 位一个字节, 共 4 个字节;
上面的例数分成字节就是: $44、$33、$22、$11, 这显着比二进制简便、比十进制直观.
此中的 $11 是最低位的字节、$44 是最高位的字节(每字节对应十六进制的两位).
偶然我们须要获取此中某个字节或某两个字节, 这固然用位运算也不难, 但照旧有了诸多函数:
Lo //获取例数中的 $11
Hi //获取例数中的 $22
LoWord //获取例数中的 $2211
HiWord //获取例数中的 $4433
此中的 Hi 似乎有点费解, 为什么获取的不是 $44 而是 $22 呢?
如许明白吧: Hi 获取的是 Lo(获取)的上一个字节.
HiByte 和 Hi 根本一样, 如果参数是 16 位的 Word 范例, 用 HiByte 会更好些(中心会省去一个转换过程).
此中的 HiWord 是个函数, 但 LoWord 并不是个函数, 它是 Word 范例的重定名.
也就是说 LoWord(num) 等价于 Word(num), 这不是范例转换吗?
是的, 以是像 Lo(num) 也可以用 Byte(num) 来取代.
用代码总结一下:
var
num: Cardinal;
b1,b2,b3,b4: Byte;
w1,w2: Word;
begin
num := $44332211;
w1 := Word(num);
w2 := HiWord(num);
ShowMessageFmt('w1:%x; w2:%x', [w1,w2]);//w1:2211; w2:4433
b1 := Lo(num);
b2 := Hi(num);
b3 := Byte(w2);
b4 := HiByte(w2);
ShowMessageFmt('b1:%x; b2:%x; b3:%x; b4:%x', [b1,b2,b3,b4]);//b1:11; b2:22; b3:33; b4:44
end;
下一个话题: 我们偶然也须要举行上面的反利用, 譬如:
把两个 Byte 合成为一个 Word;
把两个 Word 合成一个 Cardinal;
把两个 Cardinal 合成一个 Int64;
把四个 Byte 合成一个 Cardinal;
把四个 Word 合成一个 Int64 等等
上面说的 Cardinal 也可以是 Integer 或 DWORD.
完成这种工作也有不少函数:
MakeWord、MakeLong、MakeWParam、MakeLParam、MakeLResult、MAKELCID 等等.
仅就 MakeWord、MakeLong 举例:
var
num: Cardinal;
b1,b2,b3,b4: Byte;
w1,w2: Word;
begin
b1 := $11;
b2 := $22;
b3 := $33;
b4 := $44;
w1 := MakeWord(b1, b2);
w2 := MakeWord(b3, b4);
ShowMessageFmt('w1:%x; w2:%x', [w1,w2]);//w1:2211; w2:4433
num := MakeLong(w1, w2);
ShowMessageFmt('num:%x', [num]);//44332211
end;
有没有把两个 Integer 合成为 Int64 的函数呢?
没有, 固然可以写一个; 不外有更方便的处置惩罚方式, 那就是 Int64Rec 布局.
举比方下:
var
n1,n2: Cardinal;
num64: Int64;
rec: Int64Rec;
begin
n1 := $44332211;
n2 := $AABBCCDD;
rec.Lo := n1;
rec.Hi := n2;
num64 := Int64(rec);
ShowMessage(IntToHex(num64, 0)); //AABBCCDD44332211
end;
Int64Rec 更多用于反向利用:
var
n1,n2: Cardinal;
num64: Int64;
begin
num64 := $AABBCCDD44332211;
n1 := Int64Rec(num64).Lo; //或 n1 := Cardinal(num64);
n2 := Int64Rec(num64).Hi;
ShowMessageFmt('n1:%x; n2:%x', [n1,n2]);//n1:44332211; n2:AABBCCDD
end;
|