| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 6633 人关注过本帖, 7 人收藏
标题:VFP封装结构类型示例
只看楼主 加入收藏
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:10541
专家分:42927
注 册:2014-5-20
收藏
得分:0 
以下是引用吹水佬在2022-3-17 06:46:37的发言:

注意了!先截取上述示例部分相关代码,存在BUG。

继续指针的问题
示例存在一个使用指针时出现的 BUG --- 内存泄漏。
这种使用指针的错误有时还真不容易发现,因为他不是运行到相关语句时就一定会抛出异常,也许运行到一定时间后会突然抛出类似“内存不足”、“内存分配错误”等等的异常。所以,这个问题一定要重视,平时使用指针要养成良好的习惯。

  主要相关语句:

1、pFile = apiMalloc(nBuffSize)
2、pFile  = pFile + nLen + 1
3、apiFree(pFile)

先简单了解一下堆内存分配和释放过程:
调用 Malloc 时分配一块连续的内存单元,并记录这块内存的首址,同时将首址返回给调用 Malloc 的过程存放在 pFile。
调用 Free 时释放一块内存,传入的参数 pFile 是由 Malloc 分配的这块内存首址,系统先在管理分配内存块的链表里查找地址是 pFile 记录,找到时就删除这条记录,释放被管制的内存空间,给再次 Malloc 时分配使用。
问题来了,要正常 Free 就要确保 pFile 是由 Malloc 分配的这块内存首址。这里有两点是重点:一是 Malloc 与 Free 必须是成对出现的,也就是说有 Malloc 必有 Free ;二是 pFile 一定要是由 Malloc 返回的首地址的值。
好了,现在问题就清晰了,出现 BUG 的语句就是:

  pFile  = pFile + nLen + 1

执行这句后 pFile 发生改变了,已经不是这块内存首址,当执行 Free 时已经无法找到由 Malloc 分配的这块内存记录,导致释放内存资源出现异常或不能释放造成“内存泄漏”。

要避免这类错误,一定要记住:保管好由 Malloc 返回的指针。
可以这样操作:

  pTmp = pFile
  pTmp = pTmp + nLen + 1
  nLen = apiStrlen(pTmp)
  cFiles = SYS(2600, pTmp, nLen)

东指指,西指指
都医不好我的痴
今晚只有一再心思思
永远单思
2022-03-17 15:08
nbwww
Rank: 8Rank: 8
等 级:贵宾
威 望:11
帖 子:309
专家分:743
注 册:2021-1-9
收藏
得分:0 
收藏先
2022-03-17 17:14
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:10541
专家分:42927
注 册:2014-5-20
收藏
得分:0 
以下是引用csyx在2022-3-17 14:58:47的发言:


期待早日看到同样风格的取文件夹功能,vfp的GetDir函数样式跟吹版的GetFile实在不协调

图片附件: 游客没有浏览图片的权限,请 登录注册

只贴出新增加的代码,看看之前的贴出的代码自己分别加入 StructCalss.h 和 StructCalss.prg
头文件新增
程序代码:
** Browsing for directory.
#define BIF_RETURNONLYFSDIRS   0x0001  && For finding a folder to start document searching
#define BIF_DONTGOBELOWDOMAIN  0x0002  && For starting the Find Computer
#define BIF_STATUSTEXT         0x0004  && Top of the dialog has 2 lines of text for BROWSEINFO.lpszTitle and one line if
                                       && this flag is set.  Passing the message BFFM_SETSTATUSTEXTA to the hwnd can set the
                                       && rest of the text.  This is not used with BIF_USENEWUI and BROWSEINFO.lpszTitle gets
                                       && all three lines of text.
#define BIF_RETURNFSANCESTORS  0x0008
#define BIF_EDITBOX            0x0010  && Add an editbox to the dialog
#define BIF_VALIDATE           0x0020  && insist on valid result (or CANCEL)

#define BIF_NEWDIALOGSTYLE     0x0040  && Use the new dialog layout with the ability to resize
                                       && Caller needs to call OleInitialize() before using this API

#define BIF_USENEWUI           (BIF_NEWDIALOGSTYLE + BIF_EDITBOX)

#define BIF_BROWSEINCLUDEURLS  0x0080  && Allow URLs to be displayed or entered. (Requires BIF_USENEWUI)

#define BIF_BROWSEFORCOMPUTER  0x1000  && Browsing for Computers.
#define BIF_BROWSEFORPRINTER   0x2000  && Browsing for Printers
#define BIF_BROWSEINCLUDEFILES 0x4000  && Browsing for Everything
#define BIF_SHAREABLE          0x8000  && sharable resources displayed (remote shares, requires BIF_USENEWUI)

新增结构类
程序代码:
DEFINE CLASS BROWSEINFOA AS STRUCT_CALSS
    PROCEDURE init
        DIMENSION this.aSTRUCT[8,4]
        this.stInit(1,  "hwndOwner",      "N",4)
        this.stInit(2,  "pidlRoot",       "N",4)
        this.stInit(3,  "pszDisplayName", "N",4)
        this.stInit(4,  "lpszTitle",      "N",4)
        this.stInit(5,  "ulFlags",        "N",4)
        this.stInit(6,  "lpfn",           "N",4)
        this.stInit(7,  "lParam",         "N",4)
        this.stInit(8,  "iImage",         "N",4)
        STRUCT_CALSS::init
    ENDPROC
ENDDEFINE

新增API
程序代码:
    DECLARE LONG CoTaskMemFree IN Ole32 LONG
     
    DECLARE long ILCreateFromPath    IN shell32 string@ 
    DECLARE long SHBrowseForFolder   IN shell32 long
    DECLARE long SHGetPathFromIDList IN shell32 long, long

demo
程序代码:
**     
**    StructCalss_DirDialog.prg 
**     
#INCLUDE StructCalss.h
SET PROCEDURE TO StructCalss.prg ADDITIVE
LoadApi() 

? myGetDir("C:\temp")

SET PROCEDURE TO
CLEAR ALL
RETURN

FUNCTION myGetDir(cDefDir)
    LOCAL bi, pDir, cDir, pci, pit
    pDir = apiMalloc(MAX_PATH)

    cDefDir = STRCONV(ADDBS(cDefDir)+0h00, 5)
    pci = ILCreateFromPath(@cDefDir)
    
    bi = CREATEOBJECT("BROWSEINFOA")
    bi.setValue("pidlRoot",       pci)
    bi.setValue("pszDisplayName", pDir)
    bi.setValue("ulFlags",        BIF_BROWSEINCLUDEFILES)
    
    pit = SHBrowseForFolder(bi.pBuffer)
  
    IF pit > 0
        SHGetPathFromIDList(pit, pDir)
        cDir = SYS(2600, pDir, apiStrlen(pDir))
        CoTaskMemFree(pit)
    ENDIF
    CoTaskMemFree(pci)
    apiFree(pDir)
    RETURN cDir
ENDFUNC

2022-03-17 21:28
csyx
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:火星
等 级:版主
威 望:37
帖 子:640
专家分:2472
注 册:2018-3-13
收藏
得分:0 
跟取文件对话框的Vista风格还是不统一呢,希望能整出一套风格统一的对话框,随便在网上找的两张图片,照说api可以整出取文件的,取文件夹的应该也能吧,只是我不会
图片附件: 游客没有浏览图片的权限,请 登录注册
图片附件: 游客没有浏览图片的权限,请 登录注册


[此贴子已经被作者于2022-3-17 21:39编辑过]


这家伙很懒,啥也没留下
2022-03-17 21:36
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:10541
专家分:42927
注 册:2014-5-20
收藏
得分:0 
回复 34楼 csyx
这个够强大的,VFP的表单应该就可以设计出来。
如果只是取文件夹或文件名,没必要搞得那么强大。

[此贴子已经被作者于2022-3-17 21:49编辑过]

2022-03-17 21:47
csyx
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:火星
等 级:版主
威 望:37
帖 子:640
专家分:2472
注 册:2018-3-13
收藏
得分:0 
我们单位用的一套工资软件据我了解就是用vfp9写的,它的取文件和文件夹对话框就是统一的Vista风格,明天上班我截个图发上来给吹版参考下,以吹版的实力应该不难实现

这家伙很懒,啥也没留下
2022-03-17 21:52
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:10541
专家分:42927
注 册:2014-5-20
收藏
得分:0 
以下是引用csyx在2022-3-17 21:36:26的发言:
照说api可以整出取文件的,取文件夹的应该也能吧

不用API,就用VFP自己的设计器就可以,拉几个控件到表单,显示文件夹和文件用操作系统提供的列表框控件,VFP的命令就可以遍历文件夹和文件。
2022-03-17 21:57
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:10541
专家分:42927
注 册:2014-5-20
收藏
得分:0 
回复 36楼 csyx
有可能是调用 windows shell 的类
这贴主要是探讨封装调用API时用到的“结构类型”类,借调用API举例,不是设计什么完整的功能模块。
2022-03-17 22:03
csyx
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:火星
等 级:版主
威 望:37
帖 子:640
专家分:2472
注 册:2018-3-13
收藏
得分:0 
我让值班的同事给截了两张图,一张是指定备份文件的打开文件对话框,一张是指定备份路径的对话框,风格是统一的,那个打开文件对话框跟您的就一模一样,所以不会是用vfp表单做的,在不同的电脑上外观不同,但都跟Windows主题一致
我是弄不清咋做的,就希望能像调用vfp内置函数一样简单,能出来这个风格的对话框就好了
如果俺说的跑题了请见谅
图片附件: 游客没有浏览图片的权限,请 登录注册
图片附件: 游客没有浏览图片的权限,请 登录注册

图片缩小点,以免喧宾夺主


[此贴子已经被作者于2022-3-17 23:06编辑过]


这家伙很懒,啥也没留下
2022-03-17 22:51
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:10541
专家分:42927
注 册:2014-5-20
收藏
得分:0 
回复 39楼 csyx
可以试试用打开文件名对话框那个api只显示文件夹做打开文件夹对话框
2022-03-18 04:01
快速回复:VFP封装结构类型示例
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.028051 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved