我在编写一个控件时
在下面代码运行是出现内存错误
SendMessage(Hwnd, BFFM_SETSELECTION, Ord(TRUE), Longint(pChar(InitialDir)))
但是我修改为
SendMessage(Hwnd, BFFM_SETSELECTION, Ord(TRUE), Longint(pChar('E:\')))
就能顺利通过,这是为什么?
上面InitialDir为String类型

解决方案 »

  1.   

    没有错啊,你检查InitialDir的值了吗?
      

  2.   

    有检查
    我在调试的时候查看过 InitialDir='E:\'另外InitialDir是私有变量,如果我把InitialDir放到单元的全局变量中也能顺利通过,这是为什么?
      

  3.   

    InitialDir数据可能有错误。
    或者
    SendMessage(Handle, BFFM_SETSELECTION, Ord(TRUE), Longint(pChar(@InitialDir[1])))
      

  4.   

    SendMessage(Handle, BFFM_SETSELECTION, Ord(TRUE), Longint(pChar(@InitialDir[1])))
      

  5.   

    谢谢 车五
    代码如下function TFileEdit.SelectDir(InitialDir: string): string;
    function BrowseCallbackProc(hwnd: HWND; uMsg: UINT; lParam,
      lpData: Cardinal): integer; Stdcall;
    begin  
      if uMsg = BFFM_INITIALIZED then
        result := SendMessage(Hwnd, BFFM_SETSELECTION, Ord(TRUE), Longint(pChar(InitialDir)))
      else
        result := 1
    end;
    var
      TitleName: string;
      lpItemID: PItemIDList;
      BrowseInfo: TBrowseInfo;
      DisplayName: array[0..MAX_PATH] of char;
      TempPath: array[0..MAX_PATH] of char;
    begin
      FillChar(BrowseInfo, sizeof(TBrowseInfo), #0);
      BrowseInfo.hwndOwner := Handle;
      BrowseInfo.pszDisplayName := @DisplayName;
      TitleName := Title;
      BrowseInfo.lpszTitle := PChar(TitleName);
      if FNewFolder then
        BrowseInfo.ulFlags := 64
      else
        BrowseInfo.ulFlags := BIF_RETURNONLYFSDIRS;
      path := FInitialDir;
      BrowseInfo.lpfn := @BrowseCallbackProc;
      BrowseInfo.lParam := BFFM_INITIALIZED;  lpItemID := SHBrowseForFolder(BrowseInfo);
      if lpItemId <> nil then
      begin
        SHGetPathFromIDList(lpItemID, TempPath);
        Result := TempPath;
        GlobalFreePtr(lpItemID);
      end;
    end;在这个方法中本来没有带参数InitialDir,我是用私有变量
    结果都一样,能编译,不能运行(出现内存错误)现改成全局变量就没有问题了,这是为什么?
      

  6.   

    @InitialDir[1] 和InitialDir[1]的区别在那?
    使用这个也不行,只有使用全局变量才可以,现在问题虽然解决了,可我还是很郁闷,为什么?
      

  7.   

    上面打错了
    我想问的是@InitialDir[1] 和InitialDir的区别在那?
      

  8.   

    你的函数是嵌入式
    不能访问窗体的私有变量,除非这样
    function TFileEdit.BrowseCallbackProc(hwnd: HWND; uMsg: UINT; lParam,
      lpData: Cardinal): integer; Stdcall;
    begin  
      if uMsg = BFFM_INITIALIZED then
        result := SendMessage(Hwnd, BFFM_SETSELECTION, Ord(TRUE), Longint(pChar(InitialDir)))
      else
        result := 1
    end;
      

  9.   

    @InitialDir[1]表示字符串的地址,字符串下标从1开始不是0
    InitialDir代表字符串内容
    在你这用已经用PCHAR()强制转化了,Longint(pChar(InitialDir))和Longint(pChar(@InitialDir[1]))两种用法都可以
      

  10.   

    怎么就不能访问私有变量?
    我设置了断点查看,InitialDir明明就有值啊,另外,我在函数里又定义了一个
    var vDir:String;
      vDir:=InitialDir;
    这一句话也没有错啊,vDir也有值
    直到SendMessage(Hwnd, BFFM_SETSELECTION, Ord(TRUE), Longint(pChar(vDir))) 时他就出错!
      

  11.   

    SendMessage(Hwnd, BFFM_SETSELECTION, Ord(TRUE), Longint(@vDir[1]))
    这样行不?
      

  12.   

    其实原因很简单:
    SendMessage(Hwnd, BFFM_SETSELECTION, Ord(TRUE), Longint(pChar(InitialDir))) 是在回调函数中调用,
    调用时你的函数已经退出了,参数InitialDir已经不存在了,所以会内存错误。
    要正常工作,必须保证回调函数工作时,变量必须存在,用全局变量时最简单的办法。