假设按钮有如下代码:
procedure TForm1.Button1Click(Sender: TObject);
var
s:string;
begin
setlength(s,100);
s:='abcdferewf';
getwindowtext(form1.handle,pchar(s),length(s));
//s:=string(pchar(s));
showmessage(s);
end;我猜显示的是窗体的标题,但结果却是'abcdferewf'。奇怪的是去掉了s:='abcdferewf'这一句就可以了,为什么?盼望大虾们解答。(因刚注册,自己没积分,不好意思 ^_^)
procedure TForm1.Button1Click(Sender: TObject);
var
s:string;
begin
setlength(s,100);
s:='abcdferewf';
getwindowtext(form1.handle,pchar(s),length(s));
//s:=string(pchar(s));
showmessage(s);
end;我猜显示的是窗体的标题,但结果却是'abcdferewf'。奇怪的是去掉了s:='abcdferewf'这一句就可以了,为什么?盼望大虾们解答。(因刚注册,自己没积分,不好意思 ^_^)
IpString:指向接收文本的缓冲区的指针。
你的文本是S,缓冲区里面设置指向的又是S,显示的当然是S的值了,如果不对S赋值,显示就是正确的
s:='abcdferewf' 的存在让 SetLength 句成了没用的代码。此时s指向一个常量字符串,由于 PChar 的类型转换(调用 System._LStrToPChar)并不将常量字符串变量化(调用 System.UniqueString),试图改变将失败,并触发一个异常。但是由于 GetWindowText 对异常进行了处理,所以并不触发错误,而是继续执行后面的代码
如果观察 GetWindowText 句的返回值的话,会发现是0,根据msdn上对该函数返回值的说明:
If the function succeeds, the return value is the length, in characters, of the copied string, not including the terminating NULL character. If the window has no title bar or text, if the title bar is empty, or if the window or control handle is invalid, the return value is zero. To get extended error information, call GetLastError. 而GetLastError的返回值是5,根据msdn中的说明,该值是ERROR_ACCESS_DENIED
这里的S指向了一个常量,而常量是不允许修改的,API试图写这段内存失败,所以返回0如果是s:=edit1.text; //edit1里填足够长度的内容
就能正确调用