Delphi的一个Bug! 这并不是delphi的bug而是你对PCHAR不了解造成的。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 PCHAR的定义是“PCHAR=^CHAR”它是个指针它与C语言中的PCHAR用法又有些不同。C语言中该类型变量可以用直接用字串赋值,而delphi 中不行你必须先申请空间,否则指针会指向空。在delphi环境下可用因为此时正处于调试状态,所以不会出事。解决办法是:在“THEPCHAR:='C:\Temp.bmp';”前加一句"getmem(thepchar,255)" 别忘了在用完该变量后将它free掉.当然了可以将thepchar 定义成string;然后用类型转换将其转换成pcharpchar(thepchar);而edit.text 便是个字串变量所以可以解决这个问题。怎么样有点帮助吧! iamdelphiman(小程):下面的两种方法我都试过了,但是脱离delphi调试环境后都不行。请您不要笑,亲身实践一下,并告知原因,谢谢,分数非你莫数了。一。procedure TForm1.Button1Click(Sender: TObject);varTHEPCHAR:string;beginTHEPCHAR:='C:\Temp.bmp';SystemParametersInfo(SPI_SETDESKWALLPAPER, 0,pchar(THEPCHAR),SPIF_UPDATEINIFILE +SPIF_SENDWININICHANGE);end;二。procedure TForm1.Button1Click(Sender: TObject);varTHEPCHAR:pchar;begin getmem(thepchar,255); THEPCHAR:='C:\Temp.bmp'; SystemParametersInfo(SPI_SETDESKWALLPAPER, 0,THEPCHAR,SPIF_UPDATEINIFILE + SPIF_SENDWININICHANGE); FreeMem(thepchar);end; qhuojun(加非猫):确实有这回事,为什么不自己试试,这样的玩笑我也开吗?有什么高见吗?为什么我在csdn上提问,总是没有几个人有能力回答? 我也遇到过: 在Delphi IDE中能通过,退出Delphi就不能执行,到底是什么问题?????????哪儿有高手帮忙回答 就拿这个问题来说: 我加了一句判断SystemParametersInfor返回值的语句,结果为假,在IDE中GetLastError返回120(据说是在NT中才有效,而我用的是瘟酒吧),独立运行返回值为87(说参数无效)究竟问题在哪儿?? 我试了一下,两个都可以哦.是不是有其他的干扰啊?我的是Win2000 Pro+D6.不知道大家有没有碰到,执行到最后的FreeMem时候会出错,好象不允许操作.THEPCHAR:pchar;begin getmem(thepchar,255); THEPCHAR:='C:\Temp.bmp'; SystemParametersInfo(SPI_SETDESKWALLPAPER, 0,THEPCHAR,SPIF_UPDATEINIFILE + SPIF_SENDWININICHANGE); FreeMem(thepchar);<---运行的时候会出错,是不是SystemParametersInfo已经帮我们释放了?还是其他的问题end; wzzsoft(上帝身边的男孩)由于我好久没有使用Delphi了目前还是在用这Delphi4.0版本,没有这个问题呀,但是我发现你的代码里面有一个不恰当地地方。就是:THEPCHAR:='C:\Temp.bmp';这一句。不知道在Delphi5和6里面,会不会出错。正确的语句应该是StrPCopy(ThePchar,'C:\temp.bmp')。 我这样解决了:procedure TForm1.Button1Click(Sender: TObject);var THEPCHAR: array [1..26] of char;begin THEPCHAR := 'd:\photos\image\init1.bmp' + #0; SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, @THEPCHAR[1], PIF_UPDATEINIFILE or SPIF_SENDCHANGE);end; 噢?!是这样的!是有听说对PCHAR型变量直接:=赋值不安全,要用STRPCOPY,它们到底有什么不同? 是的,PCHAR 型变量直接:=赋值一定要小心,它可能不安全。最好先掌握一点 delphi 内存管理的知识: PCHAR 型其实是指针类型,所以它所指的内存要小心(用过 C 或 C++ 的朋友可能更了解这点); string 型是高级的自动管理生存期的字符串类型,使用它相当方便,你完全不用了解 GetMem、FreeMem、VirXXXX(winAPI) 内存管理函数。它会在需要的时候分配内存,在离开作用域(如函数)的时候被自动销毁。 所以当 pchar 指到的 string 字符串可能已经被销毁了。 sorry,最近在有点忙没上网今天才知道用szchengyu(cy)的方法应该最有效以前我自已重写了一个ini 单元,就是用这种办法利用 thepchar:array[0..255]of char 代替pchar , 不用getmem, 也不用freememprocedure TForm1.Button1Click(Sender: TObject);varTHEPCHAR:array[0..255] of char;beginTHEPCHAR:='C:\Temp.bmp';SystemParametersInfo(SPI_SETDESKWALLPAPER, 0,@THEPCHAR,SPIF_UPDATEINIFILE +SPIF_SENDWININICHANGE);end;而且delphi 会将char 类型的字串当成pchar 来用,c中也是如此. 其它正在试 另外freemem(thepchar)应改为freemem(thepchar,255); 否则会出错 如果是string的话,用下面语句可以通过。其实它与array 道理是一样SystemParametersInfo(SPI_SETDESKWALLPAPER, 0,@THEPCHAR[1],SPIF_UPDATEINIFILE +SPIF_SENDWININICHANGE); pchar在内存中的最后一位必须是#0否则容易出错。 感谢各位的帮助,strpcopy函数的定义为:function strpcopy(dest:pchar;source:string):pchar;strpcopy函数将pascal格式字符串source复制到0 结束的字符串dest中,strpcopy函数不进行长度检查,dest中至少需要包含length(source)+1个字符空间。因此我找到了完全解决这个问题的办法,脱离delphi的IDE后也能够正确执行,代码如下:procedure TForm1.Button1Click(Sender: TObject); var THEPCHAR:pchar; begin getmem(thepchar,255);//不用getmen可能会出错 StrPCopy(ThePchar,'C:\temp.bmp'); //不能直接用THEPCHAR := 'C:\temp.bmp' SystemParametersInfo(SPI_SETDESKWALLPAPER, 0,THEPCHAR,SPIF_UPDATEINIFILE + SPIF_SENDWININICHANGE); FreeMem(thepchar);//改用StrPCopy函数后,freemen就不会出错了end;szchengyu(cy):你的代码确也能解决这个问题,脱离delphi的IDE后也能够正确执行:procedure TForm1.Button1Click(Sender: TObject); var THEPCHAR: array [1..12] of char; //0...12是'C:\temp.bmp'的字符数加一,否则程序不能编译执行,用255也不能编译 begin THEPCHAR := 'C:\temp.bmp' + #0; SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, @THEPCHAR[1],SPIF_UPDATEINIFILE + SPIF_SENDWININICHANGE);end; 感谢各位的帮助,也同时希望各位能够通过这个问题更深刻的认识pchar指针型变量。这个问题的重点是 PCHAR型变量直接:=赋值 不安全,应该使用 strpcopy函数。具体原因在上面已经有所论述。这是问题的重点。同时还要注意正确使用getmen过程和freemen过程。freemen过程定义为procedure freemen(var p:pointer;size:word); 今天貌似是第三铁公鸡的好日子?散分庆祝下,呵呵 >>>>指点一下有什么样的组件 请教一个canvas小问题 急!!在dbgrid1中,当我输入5条记录,关掉,在打开时,5条记录的先后次序改变? 请问枚举类型变量的缺省值是多少? 我用QuickReport3.6页面预览问题... delphi如何解析这段xml???? 如何去掉MDI主窗体的水平或垂直滚动条? 那里有delphi6 for linux 下载? 有没有可以显示gif图片的构件,ocx也行啊? delphi中怎样不连接数据库直接处理表格? 应用程序退出后在任务栏中留下一个方框,怎样去掉?
C语言中该类型变量可以用直接用字串赋值,而delphi 中不行你必须先申请空间,
否则指针会指向空。在delphi环境下可用因为此时正处于调试状态,所以不会出事。
解决办法是:
在“THEPCHAR:='C:\Temp.bmp';”前加一句"getmem(thepchar,255)" 别忘了在用完
该变量后将它free掉.
当然了可以将thepchar 定义成string;然后用类型转换将其转换成pchar
pchar(thepchar);
而edit.text 便是个字串变量所以可以解决这个问题。
怎么样有点帮助吧!
下面的两种方法我都试过了,但是脱离delphi调试环境后都不行。请您不要笑,亲身实践一下,并告知原因,谢谢,分数非你莫数了。
一。
procedure TForm1.Button1Click(Sender: TObject);
var
THEPCHAR:string;
begin
THEPCHAR:='C:\Temp.bmp';
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0,pchar(THEPCHAR),SPIF_UPDATEINIFILE +
SPIF_SENDWININICHANGE);
end;二。
procedure TForm1.Button1Click(Sender: TObject);
var
THEPCHAR:pchar;
begin
getmem(thepchar,255);
THEPCHAR:='C:\Temp.bmp';
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0,THEPCHAR,SPIF_UPDATEINIFILE +
SPIF_SENDWININICHANGE);
FreeMem(thepchar);
end;
确实有这回事,为什么不自己试试,这样的玩笑我也开吗?有什么高见吗?
为什么我在csdn上提问,总是没有几个人有能力回答?
我加了一句判断SystemParametersInfor返回值的语句,结果为假,在IDE中GetLastError返回120(据说是在NT中才有效,而我用的是瘟酒吧),独立运行返回值为87(说参数无效)究竟问题在哪儿??
是不是有其他的干扰啊?
我的是Win2000 Pro+D6.不知道大家有没有碰到,执行到最后的FreeMem时候会出错,好象不允许操作.
THEPCHAR:pchar;
begin
getmem(thepchar,255);
THEPCHAR:='C:\Temp.bmp';
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0,THEPCHAR,SPIF_UPDATEINIFILE +
SPIF_SENDWININICHANGE);
FreeMem(thepchar);<---运行的时候会出错,是不是SystemParametersInfo已经帮我们释放了?还是其他的问题
end;
由于我好久没有使用Delphi了目前还是在用这Delphi4.0版本,没有这个问题呀,但是我发现你的代码里面有一个不恰当地地方。就是:
THEPCHAR:='C:\Temp.bmp';
这一句。不知道在Delphi5和6里面,会不会出错。
正确的语句应该是
StrPCopy(ThePchar,'C:\temp.bmp')。
THEPCHAR: array [1..26] of char;
begin
THEPCHAR := 'd:\photos\image\init1.bmp' + #0;
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, @THEPCHAR[1], PIF_UPDATEINIFILE or SPIF_SENDCHANGE);
end;
是有听说对PCHAR型变量直接:=赋值不安全,要用STRPCOPY,它们到底有什么不同?
最好先掌握一点 delphi 内存管理的知识:
PCHAR 型其实是指针类型,所以它所指的内存要小心(用过 C 或 C++ 的朋友可能更了解这点);
string 型是高级的自动管理生存期的字符串类型,使用它相当方便,你完全不用了解 GetMem、FreeMem、VirXXXX(winAPI) 内存管理函数。它会在需要的时候分配内存,在离开作用域(如函数)的时候被自动销毁。
所以当 pchar 指到的 string 字符串可能已经被销毁了。
用szchengyu(cy)的方法应该最有效以前我自已重写了一个ini 单元,就是用这种办法
利用 thepchar:array[0..255]of char 代替pchar , 不用getmem, 也不用freemem
procedure TForm1.Button1Click(Sender: TObject);
var
THEPCHAR:array[0..255] of char;
begin
THEPCHAR:='C:\Temp.bmp';
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0,@THEPCHAR,SPIF_UPDATEINIFILE +
SPIF_SENDWININICHANGE);
end;
而且delphi 会将char 类型的字串当成pchar 来用,c中也是如此.
其它正在试
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0,@THEPCHAR[1],SPIF_UPDATEINIFILE +
SPIF_SENDWININICHANGE);
function strpcopy(dest:pchar;source:string):pchar;
strpcopy函数将pascal格式字符串source复制到0 结束的字符串dest中,strpcopy函数不进行长度检查,dest中至少需要包含length(source)+1个字符空间。因此我找到了完全解决这个问题的办法,脱离delphi的IDE后也能够正确执行,代码如下:
procedure TForm1.Button1Click(Sender: TObject);
var
THEPCHAR:pchar;
begin
getmem(thepchar,255);//不用getmen可能会出错
StrPCopy(ThePchar,'C:\temp.bmp');
//不能直接用THEPCHAR := 'C:\temp.bmp'
SystemParametersInfo(SPI_SETDESKWALLPAPER,
0,THEPCHAR,SPIF_UPDATEINIFILE +
SPIF_SENDWININICHANGE);
FreeMem(thepchar);
//改用StrPCopy函数后,freemen就不会出错了
end;
szchengyu(cy):
你的代码确也能解决这个问题,脱离delphi的IDE后也能够正确执行:procedure TForm1.Button1Click(Sender: TObject);
var
THEPCHAR: array [1..12] of char;
//0...12是'C:\temp.bmp'的字符数加一,否则程序不能编译执行,用255也不能编译
begin
THEPCHAR := 'C:\temp.bmp' + #0;
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, @THEPCHAR[1],SPIF_UPDATEINIFILE + SPIF_SENDWININICHANGE);
end;
procedure freemen(var p:pointer;size:word);