function AnsiToUnicode(Str: AnsiString): String;
var
Len: integer;
begin
Len := Length(Str)+ 1;
SetLength(Result, Len);
Len := MultiByteToWideChar(CP_ACP, 0, PAnsiChar(Str),-1,
PWideChar(Result), Len);
SetLength(Result, Len- 1); // end is #0
end;
可是在F9的时候,提示:
[警告] MainUnit.pas(218): Suspicious typecast of String to PWideChar
[警告] MainUnit.pas(461): Comparison always evaluates to False
[错误] MainUnit.pas(995): Statement expected but 'FUNCTION' found
[警告] MainUnit.pas(1002): Suspicious typecast of String to PWideChar
[错误] MainUnit.pas(1006): Declaration expected but identifier 'AShortMessage' found
[错误] MainUnit.pas(1013): '.' expected but ';' found
function AnsiToUnicode(Str: AnsiString): String;
var
Len: integer;
begin
Len := Length(Str)+ 1;
SetLength(Result, Len);
Len := MultiByteToWideChar(CP_ACP, 0, PAnsiChar(Str),-1,
PWideChar(Result), Len);
SetLength(Result, Len- 1); // end is #0
end;
问题出在这段上面
#3
自已顶一下吧,高手在哪里
#4
function AnsiToUnicode这个根本没必要,直接两种类型互相赋值就自动转换了。
唯一的问题是从前面的代码
R^ := P^[Offset] * 256 + P^[Offset + 1];
来看,移动短信网关使用的unicode编码是大端格式,所以需要转换一下:
function AnsiToUnicodeBE(S: AnsiString): WideString;
var
i: integer;
begin
Result := S;
for i := 1 to Length(Result) do
Result[i] := WideChar(Swap(word(Result[i])));
end;
然后直接发送这个函数返回的WideString就可以了。
function AnsiToUnicodeBE(S: AnsiString): WideString;
var
i: integer;
begin
Result := S;
for i := 1 to Length(Result) do
Result[i] := WideChar(Swap(word(Result[i])));
end;
我写的这个并不是用于接收的,而是发送之前处理一下编码,你理解错了。
编码处理过之后已经变成unicode大端格式了,你再显示出来就成乱码了,因为WideString对应Windows的BSTR,固定是小端格式UTF-16,D7又不支持TEncoding,否则指定BigEndianUnicode 就可以正确显示。
要显示处理过的字符串,可以这样(也可以用于接收):
function UnicodeBEToString(S: PWideChar): WideString;
var
i: integer;
begin
Result := S;
for i := 1 to Length(Result) do
Result[i] := WideChar(Swap(word(Result[i])));
end;
#12
会不会是你理解错了。
CMPP3只能使用
if PK_CMPP_DELIVER.Msg_Fmt in [8..11, 23..25, 27] then //UCS2
begin
ShortMessage := self.My_UniCodeArrayToString(PK_CMPP_DELIVER_CONTENT.Msg_Content,PK_CMPP_DELIVER.Msg_Length)
end;
msg=8即UCS2编码来发送和接收短信。
我先表述一下,我所理解的所谓的发和收的定义 收信息,指的是手机收到网关发来的信息 发信息,指的是手机向网关发送的信息 现在发信息正常。
没错呀,我说的就是这个收发,#11写的function UnicodeBEToString(S: PWideChar): WideString;是用于显示接收到的信息(注意不是用你顶楼My_UniCodeArrayToString处理过的信息,是原始数据),可以替换My_UniCodeArrayToString,而#4写的function AnsiToUnicodeBE(S: AnsiString): WideString;是用于发送之前处理编码的,比如:
var
s: AnsiString;
w: WideString;
begin
s := '这是一个测试。xyz';
w := AnsiToUnicodeBE(s);
send(w); // 或者send(PWideChar(w), Length(w)); 假设这里的send是你用的发送信息的函数
end;
#14
procedure TMainForm.LoopTimerTimer(Sender: TObject);
var
CMPP_SUBMIT : TCMPP_SUBMIT;
//AShortMessage: string;
AShortMessage: AnsiString;//朱颜
zhuyanw: WideString; begin
if not self.CMPP3Socket.Active then Exit;;
if not My_LoginFlag then Exit;
try
(Sender AS TTimer).Enabled := false;
self.Query1.Close;
self.Query1.SQL.Text := 'SELECT TOP ' + IntToStr(self.My_MaxRecCount) + ' * FROM Submit WHERE MT_SendCount = 0';
self.CDS1.Open;
self.CDS1.First;
while not self.CDS1.Eof do
begin
if not self.CMPP3Socket.Active then Break;
FillChar(CMPP_SUBMIT,SizeOf(CMPP_SUBMIT),0);
with CMPP_SUBMIT do
begin
Msg_Id := CDS1.FieldByName('Msg_Id').AsInteger;
Pk_total := Byte(CDS1.FieldByName('Pk_total').AsInteger);
Pk_number := Byte(CDS1.FieldByName('Pk_number').AsInteger);
Registered_Delivery := Byte(CDS1.FieldByName('Registered_Delivery').AsInteger);
Msg_level := Byte(CDS1.FieldByName('Msg_level').AsInteger);
My_StrCopy(trim(CDS1.FieldByName('Service_Id').AsString),Service_Id,SizeOf(Service_Id));
Fee_UserType := Byte(CDS1.FieldByName('Fee_UserType').AsInteger);
My_StrCopy(trim(CDS1.FieldByName('Fee_terminal_Id').AsString),Fee_terminal_Id,SizeOf(Fee_terminal_Id));
Fee_terminal_type := Byte(CDS1.FieldByName('Fee_terminal_type').AsInteger);
TP_pId := Byte(CDS1.FieldByName('TP_pId').AsInteger) ;
TP_udhi := Byte(CDS1.FieldByName('TP_udhi').AsInteger);
Msg_Fmt := Byte(CDS1.FieldByName('Msg_Fmt').AsInteger);
My_StrCopy(My_SPCorpID,Msg_src,SizeOf(Msg_src));
My_StrCopy(trim(CDS1.FieldByName('FeeType').AsString),FeeType,SizeOf(FeeType));
My_StrCopy(trim(CDS1.FieldByName('FeeCode').AsString),FeeCode,SizeOf(FeeCode));
if trim(CDS1.FieldByName('ValId_Time').AsString) <> '' then
begin
My_StrCopy(trim(CDS1.FieldByName('ValId_Time').AsString),ValId_Time,SizeOf(CMPP_SUBMIT.ValId_Time));
end;
if trim(CDS1.FieldByName('At_Time').AsString) <> '' then
begin
My_StrCopy(trim(CDS1.FieldByName('At_Time').AsString),At_Time,SizeOf(CMPP_SUBMIT.At_Time));
end;
My_StrCopy(trim(CDS1.FieldByName('Src_Id').AsString),Src_Id,SizeOf(Src_Id));
DestUsr_tl := 1;
My_StrCopy(trim(CDS1.FieldByName('Dest_terminal_Id').AsString),Dest_terminal_Id,SizeOf(Dest_terminal_Id));
Dest_terminal_type := Byte(CDS1.FieldByName('Dest_terminal_type').AsInteger);
//AShortMessage := trim(self.CDS1.FieldByName('Msg_Content').AsString);//朱颜
AShortMessage := '1234567890ABC';//朱颜
zhuyanw:= My_AnsiToUnicodeBE(AShortMessage); if CMPP_SUBMIT.Msg_Fmt = 0 then AShortMessage := Copy(AShortMessage,1,159)
else AShortMessage := Copy(
zhuyanw,1,140);
if My_CanPackBadWord = '1' then AShortMessage := self.My_PackBadWord(AShortMessage);
Msg_Length := Length(AShortMessage);
My_StrCopy(AShortMessage,Msg_Content,Length(Msg_Content));
My_StrCopy(trim(CDS1.FieldByName('LinkID').AsString),LinkID,SizeOf(LinkID));
end;
self.CMPP3_SUBMIT(CMPP_SUBMIT,CDS1.FieldByName('ID').AsString);
self.CDS1.Delete;
Application.ProcessMessages;
self.My_DelayTime;
end;
finally
self.CDS1.Close;
self.Query1.Close;
(Sender AS TTimer).Enabled := true;
end;
end;
我觉得以上代码没有错误了啊,可是收到的仍然是乱码!!!!我都无语了!完全按你的方法做的啊
#15
手机收到网关发过来的短信还是乱码,具体代码请见14楼
#16
由于不了解从网关收到的信息是否包含正确的NULL终止,稍微修改一下。
测试代码:
function UnicodeBEToString(Content: PWideChar; Len: integer): WideString; // 修改了,增加了指定长度(unicode字符数量)
var
i: integer;
begin
SetLength(Result, Len);
Move(Content^, PWideChar(Result)^, Len);
for i := 1 to Length(Result) do
Result[i] := WideChar(Swap(word(Result[i])));
end;
function AnsiToUnicodeBE(S: AnsiString): WideString;
var
i: integer;
begin
Result := S;
for i := 1 to Length(Result) do
Result[i] := WideChar(Swap(word(Result[i])));
end;
procedure TForm1.Button1Click(Sender: TObject);
const
Data: array[0..11] of byte = ($8f, $d9, $66, $2f, $4e, $00, $4e, $2a, $6d, $4b, $8b, $d5); // unicode big endian编码的"这是一个测试",你可以把从网关收到的信息原始数据放到这里测试
content: PChar = @Data;
var
s: WideString;
s1: ANsiString;
begin
s := PWideChar(content);
Label1.Caption := s; // 乱码
s := UnicodeBEToString(PWideChar(content), 6);
Label2.Caption := s; // 这是一个测试
啊,有一个问题:
Move(Content^, PWideChar(Result)^, Len
* SizeOf(WideChar));
#18
啊,有一个问题:
Move(Content^, PWideChar(Result)^, Len
* SizeOf(WideChar));
出差了两天,今天回来看了一下,手机向网关发短信,再入库是没有问题了。
不过,程序发送给网关的,网关再转发给手机,手机收到的还是乱码
如下:
function AnsiToUnicodeBE(S: AnsiString): WideString;
var
i: integer;
begin
Result := S;
for i := 1 to Length(Result) do
Result[i] := WideChar(Swap(word(Result[i])));
end;
zhuyanw:= AnsiToUnicodeBE(AShortMessage);
function AnsiToUnicode(Str: AnsiString): String;
var
Len: integer;
begin
Len := Length(Str)+ 1;
SetLength(Result, Len);
Len := MultiByteToWideChar(CP_ACP, 0, PAnsiChar(Str),-1,
PWideChar(Result), Len);
SetLength(Result, Len- 1); // end is #0
end;
问题出在这段上面
#3
自已顶一下吧,高手在哪里
#4
function AnsiToUnicode这个根本没必要,直接两种类型互相赋值就自动转换了。
唯一的问题是从前面的代码
R^ := P^[Offset] * 256 + P^[Offset + 1];
来看,移动短信网关使用的unicode编码是大端格式,所以需要转换一下:
function AnsiToUnicodeBE(S: AnsiString): WideString;
var
i: integer;
begin
Result := S;
for i := 1 to Length(Result) do
Result[i] := WideChar(Swap(word(Result[i])));
end;
然后直接发送这个函数返回的WideString就可以了。
function AnsiToUnicode这个根本没必要,直接两种类型互相赋值就自动转换了。
唯一的问题是从前面的代码
R^ := P^[Offset] * 256 + P^[Offset + 1];
来看,移动短信网关使用的unicode编码是大端格式,所以需要转换一下:
function AnsiToUnicodeBE(S: AnsiString): WideString;
var
i: integer;
begin
Result := S;
for i := 1 to Length(Result) do
Result[i] := WideChar(Swap(word(Result[i])));
end;
然后直接发送这个函数返回的WideString就可以了。
现在不报错了,可以正常收到短信了,不过收到的短信为乱码。
#7
现在不报错了,不过收到的短信是乱码!!!
看了一些文档,说要把GB码转为UCS2编码。
#8
你前面不是说接收正常吗,怎么又成乱码了。
#9
要贴全代码,别人才能帮助你。
#10
function AnsiToUnicodeBE(S: AnsiString): WideString;
var
i: integer;
begin
Result := S;
for i := 1 to Length(Result) do
Result[i] := WideChar(Swap(word(Result[i])));
end;
我写的这个并不是用于接收的,而是发送之前处理一下编码,你理解错了。
编码处理过之后已经变成unicode大端格式了,你再显示出来就成乱码了,因为WideString对应Windows的BSTR,固定是小端格式UTF-16,D7又不支持TEncoding,否则指定BigEndianUnicode 就可以正确显示。
要显示处理过的字符串,可以这样(也可以用于接收):
function UnicodeBEToString(S: PWideChar): WideString;
var
i: integer;
begin
Result := S;
for i := 1 to Length(Result) do
Result[i] := WideChar(Swap(word(Result[i])));
end;
#12
我写的这个并不是用于接收的,而是发送之前处理一下编码,你理解错了。
编码处理过之后已经变成unicode大端格式了,你再显示出来就成乱码了,因为WideString对应Windows的BSTR,固定是小端格式UTF-16,D7又不支持TEncoding,否则指定BigEndianUnicode 就可以正确显示。
要显示处理过的字符串,可以这样(也可以用于接收):
function UnicodeBEToString(S: PWideChar): WideString;
var
i: integer;
begin
Result := S;
for i := 1 to Length(Result) do
Result[i] := WideChar(Swap(word(Result[i])));
end;
会不会是你理解错了。
CMPP3只能使用
if PK_CMPP_DELIVER.Msg_Fmt in [8..11, 23..25, 27] then //UCS2
begin
ShortMessage := self.My_UniCodeArrayToString(PK_CMPP_DELIVER_CONTENT.Msg_Content,PK_CMPP_DELIVER.Msg_Length)
end;
msg=8即UCS2编码来发送和接收短信。
我先表述一下,我所理解的所谓的发和收的定义 收信息,指的是手机收到网关发来的信息 发信息,指的是手机向网关发送的信息 现在发信息正常。
会不会是你理解错了。
CMPP3只能使用
if PK_CMPP_DELIVER.Msg_Fmt in [8..11, 23..25, 27] then //UCS2
begin
ShortMessage := self.My_UniCodeArrayToString(PK_CMPP_DELIVER_CONTENT.Msg_Content,PK_CMPP_DELIVER.Msg_Length)
end;
msg=8即UCS2编码来发送和接收短信。
我先表述一下,我所理解的所谓的发和收的定义 收信息,指的是手机收到网关发来的信息 发信息,指的是手机向网关发送的信息 现在发信息正常。
没错呀,我说的就是这个收发,#11写的function UnicodeBEToString(S: PWideChar): WideString;是用于显示接收到的信息(注意不是用你顶楼My_UniCodeArrayToString处理过的信息,是原始数据),可以替换My_UniCodeArrayToString,而#4写的function AnsiToUnicodeBE(S: AnsiString): WideString;是用于发送之前处理编码的,比如:
var
s: AnsiString;
w: WideString;
begin
s := '这是一个测试。xyz';
w := AnsiToUnicodeBE(s);
send(w); // 或者send(PWideChar(w), Length(w)); 假设这里的send是你用的发送信息的函数
end;
#14
procedure TMainForm.LoopTimerTimer(Sender: TObject);
var
CMPP_SUBMIT : TCMPP_SUBMIT;
//AShortMessage: string;
AShortMessage: AnsiString;//朱颜
zhuyanw: WideString; begin
if not self.CMPP3Socket.Active then Exit;;
if not My_LoginFlag then Exit;
try
(Sender AS TTimer).Enabled := false;
self.Query1.Close;
self.Query1.SQL.Text := 'SELECT TOP ' + IntToStr(self.My_MaxRecCount) + ' * FROM Submit WHERE MT_SendCount = 0';
self.CDS1.Open;
self.CDS1.First;
while not self.CDS1.Eof do
begin
if not self.CMPP3Socket.Active then Break;
FillChar(CMPP_SUBMIT,SizeOf(CMPP_SUBMIT),0);
with CMPP_SUBMIT do
begin
Msg_Id := CDS1.FieldByName('Msg_Id').AsInteger;
Pk_total := Byte(CDS1.FieldByName('Pk_total').AsInteger);
Pk_number := Byte(CDS1.FieldByName('Pk_number').AsInteger);
Registered_Delivery := Byte(CDS1.FieldByName('Registered_Delivery').AsInteger);
Msg_level := Byte(CDS1.FieldByName('Msg_level').AsInteger);
My_StrCopy(trim(CDS1.FieldByName('Service_Id').AsString),Service_Id,SizeOf(Service_Id));
Fee_UserType := Byte(CDS1.FieldByName('Fee_UserType').AsInteger);
My_StrCopy(trim(CDS1.FieldByName('Fee_terminal_Id').AsString),Fee_terminal_Id,SizeOf(Fee_terminal_Id));
Fee_terminal_type := Byte(CDS1.FieldByName('Fee_terminal_type').AsInteger);
TP_pId := Byte(CDS1.FieldByName('TP_pId').AsInteger) ;
TP_udhi := Byte(CDS1.FieldByName('TP_udhi').AsInteger);
Msg_Fmt := Byte(CDS1.FieldByName('Msg_Fmt').AsInteger);
My_StrCopy(My_SPCorpID,Msg_src,SizeOf(Msg_src));
My_StrCopy(trim(CDS1.FieldByName('FeeType').AsString),FeeType,SizeOf(FeeType));
My_StrCopy(trim(CDS1.FieldByName('FeeCode').AsString),FeeCode,SizeOf(FeeCode));
if trim(CDS1.FieldByName('ValId_Time').AsString) <> '' then
begin
My_StrCopy(trim(CDS1.FieldByName('ValId_Time').AsString),ValId_Time,SizeOf(CMPP_SUBMIT.ValId_Time));
end;
if trim(CDS1.FieldByName('At_Time').AsString) <> '' then
begin
My_StrCopy(trim(CDS1.FieldByName('At_Time').AsString),At_Time,SizeOf(CMPP_SUBMIT.At_Time));
end;
My_StrCopy(trim(CDS1.FieldByName('Src_Id').AsString),Src_Id,SizeOf(Src_Id));
DestUsr_tl := 1;
My_StrCopy(trim(CDS1.FieldByName('Dest_terminal_Id').AsString),Dest_terminal_Id,SizeOf(Dest_terminal_Id));
Dest_terminal_type := Byte(CDS1.FieldByName('Dest_terminal_type').AsInteger);
//AShortMessage := trim(self.CDS1.FieldByName('Msg_Content').AsString);//朱颜
AShortMessage := '1234567890ABC';//朱颜
zhuyanw:= My_AnsiToUnicodeBE(AShortMessage); if CMPP_SUBMIT.Msg_Fmt = 0 then AShortMessage := Copy(AShortMessage,1,159)
else AShortMessage := Copy(
zhuyanw,1,140);
if My_CanPackBadWord = '1' then AShortMessage := self.My_PackBadWord(AShortMessage);
Msg_Length := Length(AShortMessage);
My_StrCopy(AShortMessage,Msg_Content,Length(Msg_Content));
My_StrCopy(trim(CDS1.FieldByName('LinkID').AsString),LinkID,SizeOf(LinkID));
end;
self.CMPP3_SUBMIT(CMPP_SUBMIT,CDS1.FieldByName('ID').AsString);
self.CDS1.Delete;
Application.ProcessMessages;
self.My_DelayTime;
end;
finally
self.CDS1.Close;
self.Query1.Close;
(Sender AS TTimer).Enabled := true;
end;
end;
我觉得以上代码没有错误了啊,可是收到的仍然是乱码!!!!我都无语了!完全按你的方法做的啊
#15
会不会是你理解错了。
CMPP3只能使用
if PK_CMPP_DELIVER.Msg_Fmt in [8..11, 23..25, 27] then //UCS2
begin
ShortMessage := self.My_UniCodeArrayToString(PK_CMPP_DELIVER_CONTENT.Msg_Content,PK_CMPP_DELIVER.Msg_Length)
end;
msg=8即UCS2编码来发送和接收短信。
我先表述一下,我所理解的所谓的发和收的定义 收信息,指的是手机收到网关发来的信息 发信息,指的是手机向网关发送的信息 现在发信息正常。
没错呀,我说的就是这个收发,#11写的function UnicodeBEToString(S: PWideChar): WideString;是用于显示接收到的信息(注意不是用你顶楼My_UniCodeArrayToString处理过的信息,是原始数据),可以替换My_UniCodeArrayToString,而#4写的function AnsiToUnicodeBE(S: AnsiString): WideString;是用于发送之前处理编码的,比如:
var
s: AnsiString;
w: WideString;
begin
s := '这是一个测试。xyz';
w := AnsiToUnicodeBE(s);
send(w); // 或者send(PWideChar(w), Length(w)); 假设这里的send是你用的发送信息的函数
end;
手机收到网关发过来的短信还是乱码,具体代码请见14楼
#16
由于不了解从网关收到的信息是否包含正确的NULL终止,稍微修改一下。
测试代码:
function UnicodeBEToString(Content: PWideChar; Len: integer): WideString; // 修改了,增加了指定长度(unicode字符数量)
var
i: integer;
begin
SetLength(Result, Len);
Move(Content^, PWideChar(Result)^, Len);
for i := 1 to Length(Result) do
Result[i] := WideChar(Swap(word(Result[i])));
end;
function AnsiToUnicodeBE(S: AnsiString): WideString;
var
i: integer;
begin
Result := S;
for i := 1 to Length(Result) do
Result[i] := WideChar(Swap(word(Result[i])));
end;
procedure TForm1.Button1Click(Sender: TObject);
const
Data: array[0..11] of byte = ($8f, $d9, $66, $2f, $4e, $00, $4e, $2a, $6d, $4b, $8b, $d5); // unicode big endian编码的"这是一个测试",你可以把从网关收到的信息原始数据放到这里测试
content: PChar = @Data;
var
s: WideString;
s1: ANsiString;
begin
s := PWideChar(content);
Label1.Caption := s; // 乱码
s := UnicodeBEToString(PWideChar(content), 6);
Label2.Caption := s; // 这是一个测试
啊,有一个问题:
Move(Content^, PWideChar(Result)^, Len
* SizeOf(WideChar));
#18
啊,有一个问题:
Move(Content^, PWideChar(Result)^, Len
* SizeOf(WideChar));
出差了两天,今天回来看了一下,手机向网关发短信,再入库是没有问题了。
不过,程序发送给网关的,网关再转发给手机,手机收到的还是乱码
如下:
function AnsiToUnicodeBE(S: AnsiString): WideString;
var
i: integer;
begin
Result := S;
for i := 1 to Length(Result) do
Result[i] := WideChar(Swap(word(Result[i])));
end;
zhuyanw:= AnsiToUnicodeBE(AShortMessage);