我的杂记一

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

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;

相关推荐
专注VB编程开发20年5 天前
delphi死嗑Pascal冷门编程语言,Borland不认可 “通用多语言 IDE”,认为 “专有语言才是护城河”
开发语言·ide·delphi
专注VB编程开发20年5 天前
Delphi 的VCL控件库无法公开给其他编程语言调用
开发语言·delphi
qqww15513 天前
DelphiSpeedUp 介绍
delphi
xyzhan18 天前
使用Delphi开发混凝土生产车间自动化过程控制系统的仿真系统
运维·物联网·自动化·delphi·仿真·混凝土车间
pcplayer2 个月前
Delphi程序和大模型交互之二
人工智能·ai·大模型·agent·delphi
xyzhan2 个月前
RAD Studio Amalthea Delphi 13.1 Beta深度解析:Delphi重磅更新,原生支持Windows ARM64EC
windows·delphi·rad studio·c++ builder·delphi 13
delphi 三层源码框架3 个月前
delphi发送SSL 465端口邮件
ssl·delphi·发送邮件·indy 465端口
tanqth5 个月前
Delphi跨平台开发中为Linux开发的优劣分析
跨平台·delphi·分析·linux开发
pcplayer6 个月前
Delphi 结构体序列化为二进制串
delphi
BillKu7 个月前
在 Delphi 5 中获取 Word 文档页数的方法
word·delphi