我的杂记一

以下内容来源于网络,都是有质量的文字,如有异议请告知。

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 =packed record

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;

相关推荐
BillKu4 天前
在 Delphi 5 中获取 Word 文档页数的方法
word·delphi
BillKu7 天前
Delphi 5 中操作 Word 表格时禁用鼠标交互
word·delphi
看那山瞧那水7 天前
DELPHI 利用OpenSSL实现加解密,证书(X.509)等功能
delphi·openssl
lincats17 天前
一步一步学习使用FireMonkey动画(6) 用实例理解动画的运行状态
ide·delphi·livebindings·delphi 12.3·firemonkey
lincats18 天前
一步一步学习使用FireMonkey动画(3) 使用Delphi的基本动画组件类
ide·delphi·delphi 12.3·firemonkey
lincats19 天前
一步一步学习使用FireMonkey动画(1) 使用动画组件为窗体添加动态效果
android·ide·delphi·livebindings·delphi 12.3·firemonkey
lincats23 天前
一步一步学习使用LiveBindings(16)使用代码创建LiveBindings绑定
delphi·livebindings·delphi 12.3·firedac·firemonkey
lincats1 个月前
一步一步学习使用LiveBindings(14)TListView进阶使用(2),打造天气预报程序
delphi·livebindings·delphi 12.3·firedac·firemonkey·tlistview
lincats1 个月前
一步一步学习使用LiveBindings(13) TListView的进阶使用(1)
delphi·livebindings·delphi 12.3·firemonkey·tlistview
lincats1 个月前
一步一步学习使用LiveBindings(12) LiveBindings与具有动态呈现的TListView
delphi·livebindings·delphi 12.3·firemonkey