Skip to content

仓储台账中商品期初的算法

在做库存台账时,经常是要计算期初、入库、出库、库存的。其基本算法是期初+入库-出库=库存。入库、出库、库存都好进行统计,主要是期初的算法有些麻烦。

  1. 每次生成台账时都保存记录的话,期初只接用上次台账的库存数据就行了。但这种方法时间选择就十分固定了。
  2. 每次都动态生成台账,那么期初也只能动态生成。此时必然会有两个日期:startDate\endDate。算期初也有两种算法:
    1. 直接将早于startDate的入库数量减去早于startDate的出库数量,得出期初
    2. 未出库并且入库时间小于startDate的数量加上已出库,但出库日期大于等于startDate,并且入库时间要小于startdate的数量就能得到期初。但这种方法要知道每个商品的进出日期。

用Buildroot为OK6410编译系统

Buildroot是一个Makefiles和patches的命令集,它可以非常简单的为你的目标系统产生一个交叉编译工具链和根文件系统。现在用Buildroot给OK6410开发个嵌入式linux操作系统。

下载OK6410文件

首先下载Buildroot(2011),解压到buildroot-2011.11目录下,并且在buildroot-2011.11目录内创建一个dl目录。

下载OK6410的ubootkernel文件。分别解压到uboot和kernel目录中。进uboot目录,输入make clean && make distclean&& make smdk6410_config。编辑Makefile,将其中的"CROSS_COMPILE=/usr/local/arm/4.4.1/bin/arm--"屏蔽。退出目录,将uboot目录压缩成uboot1.1.6.tar.gz。进入kernel目录,输入make clean。并将FORLINX6410_CFG文件拷贝到arch/arm/configs目录下,并改名为smdk6410onenand_defconfig。退出目录,将kernel目录压缩成kernel3.0.1.tar.gz文件

将uboot1.1.6.tar.gz和kernel3.0.1.tar.gz文件移动到builroot-2011.11/dl/内。

配置buildroot

进入buildroot-2011.11目录,输入"make menuconfig"进行buildroot的配置。

按下面显示进行基本配置

Target Architecture (i386) --->
              (X) arm

Target Architecture Variant (generic_arm) --->
              (X) arm1176jzf-s
Target (EABI) --->
              (X) EABI

因飞凌的U-boot源代码不全,无法使用最新版的工具链,必须使用旧的工具链。

Toolchain --->
         Toolchain type --->
              (X) External toolchain
         Toolchain (Sourcer CodeBench ARM 2009q3) --->
              (X) Sourcer CodeBench ARM 2009q3
         [*] Download toolchain automatically
System configuration --->
         (ttySAC0) Port to run a getty (login prompt) on
         Baudrate to use (115200)
Package selection for the target --->
         [*] Busybox
                Busybox version (BusyBox  1.19.x)
Filesystem images --->
          [*] cramfs root filesystem
          [ ] tar the root filesystem (Unselect this option)

设置U-boot:

Bootloaders --->
          [*] U-Boot --->
                (smdk6410) U-boot board name
                 U-boot version (Custom tarball) --->
                (uboot1.1.6.tar.gz) URL of custom U-Boot tarball

设置编译的内核

Kernel --->
        [*] Linux Kernel
                Kernel version (Custom tarball)  --->
                (kernel3.0.1.tar.gz) URL of custom kernel tarball
                Kernel configuration (use a defconfig) --->
                (smdk6410onenand) Defconfig name
                Kernel binary format (zImage) --->

如想增加Qt支持,则做如下配置

Package Selection for the target --->
        Graphic libraries and applictaions (graphic/text) --->
            [*] Qt --->

编译

设置完成后,运行"make"进行编译。如无问题,则在buildroot-2011.11/output/image目录下生成u-boot.bin、zImage、rootfs.cramfs三个文件。将三个文件烧写到OK6410即可。

Tagged ,

OK6410编译Uboot、kernel(3.0.1)

入手一块飞凌OK6410,尝试重新编译uboot,kernel和Qt。

arm-linux-gcc-4.4.1ubootkernel拷贝到Ubuntu 11下。

以root模式,创建一个/usr/local/arm目录。将下载下来的arm--gcc-4.4.1解压到该目录中。即arm目录下有个4.4.1目录。

在~目录下创建一个forlinux目录,解压下载回来的uboot和kernel.

1. 修改/etc/profile文件,在后面添加路径:

 PATH="/usr/local/arm/4.4.1/bin:$PATH"

export PATH

2.修改uboot根目录下的Makefile文件,修改编译器:  

 CROSS_COMPILE=/usr/local/arm/4.4.1/bin/arm-linux-

 

进入uboot目录后,make clean&& make smdk6410_config&&make  编译完成uboot

进入kernel目录 ,make zImage编译内核文件。

此时,uboot和kernel都已编译完成,可按说明书烧写到OK6410中。

 

Tagged ,

打开路由与远程访问时 出现MMC无法创建管理单元

打开路由与远程访问时 出现MMC无法创建管理单元。如下图所示

可试从可正常打开的系统中,拷贝mprsnap.dll到这个有问题的系统中。

保险,“保险”吗?

下面这个视频中,还是有些地方定义不正确。观看时请注意下:

  • 终身寿险并非是终身交费,而是指终身提供死亡或全残保障的保险,一般到生命表的终极年龄100岁为止。根据终身寿险缴费方式的不同,可分为终身交费和限期缴费。
Tagged

保险基本概念(转)

 

1.保险人:指与投保人订立保险合同,并承担赔偿或者给付保险金责任的保险公司。
 
2.投保人:指与保险公司订立保险合同,并按照保险合同负有支付保险费义务的人。 
 
3.被保险人:指其身体或生命受保险合同保障,享有保险金请求权的人。 
 
4.受益人:指人身保险合同中由被保险人或者投保人指定的享有保险金请求权的人。 
 
5.保险利益:又称可保利益,指投保人对保险标的具有法律上承认的利益。 
 
6.保险费:简称保费,指投保人交付给保险公司的钱。 
 
7.保险金:指保险事故发生后被保险人或受益人从保险公司领取的钱。 
 
8.保险金额:简称保额,指保险公司承担赔偿或者给付保险金责任的最高限额。 
 
9.保险责任:指保险公司承担赔偿或者给付保险金责任的项目。 
 
10.除外责任:指保险公司不予理赔的项目,如违法行为或故意行为导致的事故。 
 
11.主险与附加险:主险指可以单独投保的保险险种,附加险指不能单独投保,只能附加于主险投保的保险险种,主险因失效、解约或满期等原因效力终止或中止时,附加险效力也随之终止或中止。 
 
12.现金价值:是指保户在退保时可取回的现金。由于长期寿险通常采用均衡保险费,投保人交费若干期后,将会形成一定的责任准备金,责任准备金是对被保险人的一种负债。因此,在解约退保时,退保人需将这部分负债返还给投保人。保单的现金价值正是以责任准备金为基础计算的。因投保初期投保人交费少,保单成本摊销大,所以前期现金价值很低。 
 
13.保险期间:根据寿险合同,寿险公司在约定时间内对约定的保险事故负保险责任,该约定的时间称为保险期间,也称保障期,各个不同的险种有不同的保险期间,如航空旅客人身意外伤害保险,其保险期间仅为一个航程,如果是终身寿险,保险期间则指被保险人的有生之年。 
 
14.缴费期:又称供款期,即在寿险合同中预先约定的投保人支付保险费的期间,按缴费方式不同可分为一次性缴旨(趸缴),年缴等不同方式。 
 
15.等待期:又称观察期,或免责期,是指寿险合同在生效的指定时期内,即使发生保险事故,保险人也不能获得保险赔偿,这段时期称为等待期。等待期是为了防止投保人明知道将发生保险事故,而马上投保以获得的行为,也就是所说的逆选择。 
 
16.核保:指寿险公司对保险对象的风险进行评估,决定是否接受保户的投保以及以什么条件来接受投保的过程。 
 
17.保险费自动垫交:分期交付保险费的保单,在超过宽限期仍未交付保险费的,如本保单当时具有现金价值,且现金价值扣除欠交保险费及利息,借款及利息后的余额足以垫交到期应交保险费时,保险公司将自动垫交该项欠交保险费,使保险合同继续有效,这就被称为保险费自动垫交。 
 
18.减额交清:在保单具有现金价值的情况下,投保人可以按本保单当时的现金价值在扣除欠交的保险费及利息,借款及利息后的余额,作为一次交清的全部保险费,以相同的合同条件减少保险金额,使保单继续有效。 
 
19.保单借款:在保单有效期内,如果本保单已具有现金价值,投保人可以书面形式向保险公司申请借款,最高借款金额不得超过该保单当时的现金价值在扣除欠交保险费及利息,借款及利息后余额的百分之七十,每次借款时间不得超过6个月。
 
20.可转换权益:在保单有效期内,投保人可于该保单生效满二年后任一年的生效对应日将该保单转换为保险公司当时认可的终身保险,两全保险或养老保险而无需核保,但新保单的保险金额最高不超过原保单的保险金额,且被保险人年满45周岁的生效对应日以后不再享有此项权益。转换后的新保单将于转换日开始生效,并将按原保单核保等级,转换之日被保险人的年龄及新保单的费率计算保险费。
Tagged

保险种类-定期险

在讲定期险之前,先讲个故事吧

《盘子的故事》

100个学徒工来到一家五星级大酒店学习厨艺,他们要勤勤恳恳学习十年才能出师。学徒们的薪水不高,一年只有几百块,但是五星级酒店的餐具都非常名贵,一个盘子要1000块钱。如果哪个学徒不小心打坏了一个盘子,那么他不仅要倾家荡产来赔偿这1000元钱,还可能会被开除,不能再继续学习和工作。因此学徒们都非常小心谨慎,但还是每年都有人打碎盘子。

这一年,酒店来了个聪明的财务,他提出了一个方案:如果每个学徒每年愿意交一点点钱,把这些钱集中起来,那么无论谁打碎了盘子,就用这钱来赔偿盘子,而且学徒们都不再受到处罚。大家都觉得这个方案很好,都愿意花一点点钱买个心安。那么需要交多少钱呢?聪明财务就问大家:“你们一年之内大约会打碎几个盘子?”大家想了想答到:“大约四个吧”(预定死亡率)。那么假定一年内需要赔偿四个盘子的话,就需要每个人交40元钱。聪明的财务又建议大家聘请一名经纪人来帮助大家管理这些钱财。按照当时的市场情况,雇佣一名经纪大概一年需要600元,为经纪人租个办公室要400元(预定费用)。这1000元的费用分摊到每个学徒身上是10元,这样算下来每个学徒一年只交40(保障成本)+10(费用)=50元,就可以打碎盘子不被开除了。(短期消费险诞生了)

可是这一年大半年过去了,竟然还没有人打碎盘子,这时候,一个平时做事最谨慎小心的人想了,我是最不可能打碎盘子的,这一年损失50块钱,十年也是500块啊!不行,我得找财务去谈谈。小心人跟财务这么一说,财务说:那简单,你不想交就不交呗,反正出了事风险自己承担。小心人想想又觉得不踏实:万一我打碎了盘子还是赔不起的,有没有两全其美的办法啊?聪明财务脑子一转,既然他想要拿回本金,我就要多收他一些钱,用这些多收到的钱去投资,用投资的收益把他的本金赚回来。那么现在的市场收益率大概是12.4%(预定利率,现在保监委规定预定利率不得大于2.5%)。通过计算10年后要想拿回本金,现在就收取40(赔盘子)+10(费用)+50(为回本投资)=100元。

于是聪明的财务说:我也相信你不会打碎盘子的,但是万一的事情谁也不敢担保,要不你看这样吧,你每年交100块押金(两全险),如果打碎了盘子这押金就没收了,如果十年都没打碎,到时候1000块钱我原样还你。小心人自己一算,几年内打碎了盘子,本来要赔1000的,现在如果十年中途打碎只要赔几百,如果十年都没打碎盘子,自己一分钱都没损失,确实两全其美!“但是咱们得有一个约定”财务又说,“你既然按100交押金了,这十年都得交,中途也不能再把押金取回,否则要算你违约。”小心人想想自己总归不亏,就一口承诺:“没问题!” (两全保险诞生)

这一年小心人果然没有打碎盘子,看见其他工友大都损失了50块钱,他不禁得意起来,把自己的方案告诉几个好朋友。很快一传十十传百,大家都觉得自己没那么倒霉就是那个会打碎盘子的人,于是纷纷要求交押金。财务也很乐意,于是第二年一下子收了10000元押金。财务留下4000元准备赔盘子的钱,1000元费用,剩下5000元就去投资,这一年市场非常的好,投资回报率升高到了15%(利差益,预定利率12.4%),而且这一年学徒们打碎的盘子也只打碎了3个(死差益),雇佣的经纪也只花了500(费差益)。到了年底,还赚了不只一个盘子的钱。

听说了这个事情,小心人又不平起来,他找到财务说,原来你用我们的钱去赚了那么多钱,却不分给我们,太不公平了。财务想了想说:我赚钱是靠自己的脑力体力,也有我的功劳。要不这样吧,你再多交点,每年150元(分红险),十年后我不仅还你1500,还每年把盈利的70%分给你,如何?小心人一听,觉得这样更划算,于是自己马上交了150,回去还鼓动别的工友也多交一点。

这一年恰逢股市大涨,财务赚了很多,到了年终,大家一看自己的帐户,非但没有像去年一样花掉50块,反而还多了几块钱红利。于是财务鼓动大家说,明年行情还会很好,大家不如把自己不急用的钱都给我吧,除了扣除帮大家赔付打碎盘子的保障成本40元钱,以及扣除管理费用10元。其余多给我的钱我帮你们运作,我每个月给你们结算利息,而且是利滚利。“可是我们交了那么多钱,万一要急用咋办呢?”有人问。财务说,那没关系,这部分钱急用的时候你们可以随时取出(万能险)。“那你要投资亏了怎么办?”又有人担心的问道。“放心吧,我给你们承诺每月给大家的利息不会低于0%的。而且年利率一定在2.5%以上”,众人一盘算,我们哪里懂什么投资运作,财务是个聪明人,交给他放心!于是众人你150,他180的都交了出来。 (万能险)

第三年年末,大家帐户上果然又多了若干盈余,有人感觉赚的真不少,但也有人感觉投的钱不少没有赚到心目中所想要得到的钱。他们又找到了聪明的财务,财务说:收益高的项目当然有,但是风险也大,如果你们不怕风险,我可以帮你们投到这些项目中去,这样吧,我帮大家设置几个投资的帐户,其中有风险高的,有风险低的,大家可以根据自己的偏好来选择投资的帐户,选择好了,我来帮你们运作,我每年只按帐户价值的百分之几收大家一点管理费,其余赚多少都归你们,但是万一亏了,请大家也别怪我(投连险)只要存满五年,我连手续费都不扣。大家感觉这样能赚到更多的钱,于是就把所有的钱交给了财务。

这时候来了一个新的学徒,众人纷纷向他解释这个项目的吸引力,劝他多拿一点钱出来。新学徒听得一头雾水,最后终于搞清楚来龙去脉,说:不就是交50块钱赔盘子吗?我家庭困难,不把这20%的工资都押进去行么?

 

从上面这个小故事中,可以知道寿险至少分为以下几种类型:

 

定期险即保险期有时间限制,并且到期无返还的保险,最常见的定期险有意外险、定期寿险、定期重疾等。意外险只能保一年,需要年年投保。而定寿和定重都是可以保多年,可趸缴,也可每年缴费。

定期险因无到期返还的功能,并且保险期也有限制,因此可以用少量保费做到高额的保额。可以说定期险是最实在的险种了。

有人会认为我交了这多的保费,没出险那这些保费不是都是白白打水漂了?其实买保险与买彩票性质都是一样的,都是在赌明天会不会“中奖”。只不过一个是在赌明天会不会出事故,而另一个是在赌明天会不会中奖。买彩票没中奖的话,你买彩票的钱还不是打水漂了。保险也是一样的,没出险那保费也不会退还给你的。如有到期退还的钱,那都是从你手中多拿一部分的钱,再用这些钱进行投资,再从投资收益中扣出投资成本后才能返还给你。羊毛出在羊身上,保险公司也不是慈善家。

 

Tagged

VPN拨号报错误720

今天使用VPN时,报错误720。网上搜索了一下,估计是TCP/IP协议有问题,重装下协议就可以了。

  1. 删除注册表中以下两个键:
    HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Winsock
    HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Winsock2
  2. 在系统目录的 inf 目录里面找到 nettcpip.inf 文件,打开,找到: [MS_TCPIP.PrimaryInstall] ; TCPIP has properties to display Characteristics = 0xA0 ; NCF_HAS_UI | NCF_NOT_USER_REMOVABLE 把此处的 0xA0 改为 0×80 保存退出(该设置就是允许用户修改TCP/IP协议)
  3. 打开“本地连接”的属性——安装——添加协议——从磁盘安装,找到刚刚保存的 nettcpip.inf 文件,按“确定”后,回到列表,选择最后一项“Internet 协议 (TCP/IP)”(左侧没有图标的,注意不是那个“Microsoft TCP/IP 版本 6”),会提示没有数字签名,按确定安装即可。 经过这一步之后,又返回网络连接的窗口,这个时候,选择“TCP/IP”后,那个“卸载”按钮已经是可用的了(未做这一步之前是灰色的)。点这个“卸载”按钮来把 TCP/IP 协议删除,然后重启一次机器。
  4. 重启后,把 nettcpip.inf 文件改回来(注:可改也可不改),再照着第3步,重新安装一次 TCP/IP 协议(此时它不会再提示没有数字签名了)。
  5. 安装好协议后重启一次,重新设置“本地连接”的连接属性,就可以联网了,如果还不行,就再重启一下。

几款少儿定期重疾比较

重疾比较
  等待期 生存期 费率(0岁/10万/20年) 身故 合同条款
人保健康守护天使少儿特定疾病 1年 28天 14.9(趸缴) 退保费 下载
人保健康守护天使少儿重大疾病 1年 28天 78.8(趸缴) 退保费 下载
人保健康关爱专家定期重疾 非意外伤害,180天   150 赔保额 下载
泰康 e 顺少儿重大疾病 非意外伤害,90天   200   下载
合众定期重大疾病 180天 30天 160 退保费 下载

 

  人保健康守护天使少儿特定疾病 人保健康守护天使少儿重大疾病 人保健康关爱专家定期重疾 泰康 e 顺少儿重大疾病 合众定期重大疾病
恶性肿瘤 √(只保白血病)
急性心肌梗塞        
脑中风后遗症        
重大器官移植术或造血干细胞移植术  
冠状动脉搭桥术        
终末期肾病  
急性或亚急性重症肝炎  
良性脑肿瘤  
慢性肝功能衰竭失代偿期      
脑炎后遗症或脑膜炎后遗症      
深度昏迷      
双耳失聪  
双目失明  
瘫痪    
心脏瓣膜手术    
严重阿尔茨海默病        
严重脑损伤    
严重帕金森病        
严重Ⅲ度烧伤  
严重原发性肺动脉高压      
严重运动神经元病        
语言能力丧失    
重型再生障碍性贫血  
主动脉手术    
终末期慢性呼吸功能衰竭        
系统性红斑狼疮性肾炎        
严重多发性硬化症        
严重肌营养不良症        
急性出血坏死性胰腺炎         
严重幼年型类风湿关节炎      
细菌性脑脊髓膜炎        
植物人        
I型糖尿病      
严重胃肠炎        
严重心肌炎        
艾滋病      
川崎病        
脊髓灰质炎        
疾病或外伤所致智力障碍        

 

 

  • 泰康e顺只保一年,每年要自己从网上购买。
Tagged

给其它程序上增加一个新菜单以及响应点击事件

主要有以下几个关键点:

  1. 用CreateProcess打开程序。
  2. 用AppendMenu给打开的程序增加菜单。
  3. 用shared memory传递变量。
  4. 用全局hook方式给打开的程序挂上WH_GETMESSAGE钩子。
  5. 在hook函数中,wParam=PM_REMOVE 表示消息从消息队列中移出,PMsg(lParam).message = WM_COMMAND 表示点击消息,PMsg(lParam).hwnd = pShareMem^.InstHandle 表示消息产生程序的handle,HiWord(PMsg(lParam).wParam) = $0 表示该事件是由菜单产生的,loword(PMsg(lParam).wParam)表示菜单ID号。
?View Code DELPHI
program demo;
 
uses
  Windows, Messages,
  SysUtils,
  Classes,
  Forms,
  Controls,
  ShellAPI;
 
{$R *.res}
procedure StartMsg(dwThreadId: DWORD); stdcall;
external 'Hook.dll' name 'StartMsg';
procedure StopMsg; external 'Hook.dll' name 'StopMsg';
 
type
 
  PShared = ^TShared;
 
  TShared = record
    InstHandle: DWORD;
    messageId: DWORD;
 
  end;
 
const
  WM_HOOKMSG = WM_USER + $1000;
  _mapFile = '_msgHookMap';
 
  var
   zAppName: array [0 .. 512] of Char;
  zCurDir: array [0 .. 255] of Char;
  WorkDir: string;
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
  aVisibility: integer;
  d: DWORD;
  gui: TGUITHREADINFO;
 
  myMenu, s, s1: HMENU;
  myHwnd: HWND;
 
  FileMapHandle: THandle;
  pShareMem: PShared;
 
begin
  Application.Initialize;
 
 Application.Initialize;
  // Application.MainFormOnTaskbar := True;
 
  // load exe
 
  try
    StrPCopy(zAppName, 'notepad.exe');
    GetDir(0, WorkDir);
    StrPCopy(zCurDir, WorkDir);
    FillChar(StartupInfo, SizeOf(StartupInfo), #0);
    StartupInfo.cb := SizeOf(StartupInfo);
    StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
    StartupInfo.wShowWindow := SW_SHOWMAXIMIZED;
    if not CreateProcess(nil, zAppName, nil, nil, false,
      Create_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo,
      ProcessInfo) then
    begin
 
      // result := 0;
      Exit;
    end
    else
    begin
      WaitforInputIdle(ProcessInfo.hProcess, 30000);
 
      FillMemory(@gui, SizeOf(TGUITHREADINFO), 0);
      gui.cbSize := SizeOf(TGUITHREADINFO);
      if (GetGUIThreadInfo(ProcessInfo.dwThreadId, gui)) then
      begin
        // gui.hwndActive就是子进程主窗口的句柄
 
        myHwnd := gui.hwndActive;
        myMenu := getMenu(myHwnd);
 
        if (myMenu <> 0) then
        begin
          AppendMenu(myMenu, MFT_STRING, // UINT uFlags,	// menu-item flags
            101, // UINT uIDNewItem,	// menu-item identifier or handle of drop-down menu or submenu
            Pchar('测试') // LPCTSTR lpNewItem	// menu-item content
            );
          SetMenu(myHwnd, myMenu); // MainM.Handle );
        end;
 
      end;
 
      if pShareMem = nil then
      begin
        FileMapHandle := OpenFileMapping(FILE_MAP_WRITE, false, _mapFile);
        if FileMapHandle = 0 then
          Exception.Create('Unable to access shared memory. Program halt.');
        pShareMem := MapViewOfFile(FileMapHandle,
          FILE_MAP_WRITE or FILE_MAP_READ, 0, 0, 0);
        if pShareMem = nil then
        begin
          CloseHandle(FileMapHandle);
          Exception.Create('Unable to map to shared memory. Program halt.');
        end;
      end;
      if pShareMem = nil then
        Exit; // Halt program if unable to create/open/map shared memory.
 
      StartMsg(myHwnd);
      WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
      StopMsg;
      GetExitCodeProcess(ProcessInfo.hProcess, d);
 
  //    Application.Run;
    UnMapViewOfFile(pShareMem);
CloseHandle(FileMapHandle);
    end;
  finally
  end;
end.
?View Code DELPHI
unit UnitHookMsg;
 
interface
 
uses windows, messages, SysUtils,Dialogs ;
 
type
 
  PShared = ^TShared;
 
  TShared = record
    InstHandle: DWORD;
    messageId: DWORD;
 
  end;
 
const
  WM_HOOKMSG = WM_USER + $1000;
  _mapFile = '_msgHookMap';
 
var
  NextHook: HHook;
 
  FileMapHandle: THandle;
  pShareMem: PShared;
  // PViewInteger: ^Integer;
 
procedure StartMsg(handle: DWORD); stdcall;
procedure StopMsg; stdcall;
 
implementation
 
procedure SaveInfo(k: Integer; str: string); stdcall;
var
  f: textfile;
  WorkPath: string;
begin
  WorkPath := ExtractFilePath(ParamStr(0));
  assignfile(f, WorkPath + 'Records.txt');
  if fileexists(WorkPath + 'Records.txt') = false then
    rewrite(f)
  else
    append(f);
  // if strcomp(pchar(str),pchar('#13#10'))=0 then writeln(f,'')
  // else write(f,str);
  writeln(f, str + '----$' + inttohex(k, 6));
  closefile(f);
end;
 
function HookHandler(Code: Integer; wParam: wParam; lParam: lParam): LRESULT; stdcall;
 
var
  msg1: PMsg;
begin
  if Code = HC_ACTION then
  begin
 
    msg1 := PMsg(lParam);
    if (wParam = PM_REMOVE) and (msg1.message = WM_COMMAND) and
      (msg1.hwnd = pShareMem^.InstHandle) then
    begin
      // 菜单产生
      if HiWord(msg1.wParam) = $0 then
      begin
        // LOWORD(msg1.wParam) menuId
        if loword(msg1.wParam) = 101 then
        begin
         // SaveInfo(pshareMem^.InstHandle,'hd');
          // PostMessage(PViewInteger^,WM_HOOKMSG,wParam,lParam);
          Dialogs.MessageDlg('test.', mtInformation,
      [mbOk], 0, mbOk);
 
        end;
      end;
 
    end;
 
  end;
  Result := CallNextHookEx(NextHook, Code, wParam, lParam);
 
end;
 
procedure StartMsg(handle: DWORD); stdcall;
var
  id: DWORD;
begin
  id := GetWindowThreadProcessId(handle, nil);
 
  pShareMem^.InstHandle := handle;
  // NextHook:=SetWindowsHookEx((*WH_GETMESSAGE,WH_CALLWNDPROCRET*)WH_CALLWNDPROC, HookHandler, HInstance , 0);
  NextHook := SetWindowsHookEx(
    (* WH_GETMESSAGE,WH_CALLWNDPROCRET *) WH_GETMESSAGE, HookHandler,
    HInstance, id);
  (* HOOK在MySpy里是用的最多的技术,从获取密码到截获系统的消息都是HOOK技术,可以说这
    个技术已经不是什么技术了,网上随便一个编程站点都可以找到相关介绍资料,但截获系统
    消息的还是比较麻烦的,作者就介绍一下它吧,截获系统消息无非是安装系统钩子WH_CALLWNDPROC、
    WH_CALLWNDPROCRET和WH_GETMESSAGE,为什么要安装这么多,因为系统消息有很多不同的类型,
    有Send,Post还有处理消息返回也是需要截获的,当然如果你对系统菜单也感兴趣,还需要安
    装WH_SYSMSGFILTER钩子,因为这是一个系统范围的钩子,所以必须编写成为DLL,而核心代码
    也不过就是:
 
    WH_CALLWNDPROC和WH_CALLWNDPROCRET Hooks使你可以监视发送到窗口过程的消
    息。系统在消息发送到接收窗口过程之前调用WH_CALLWNDPROC Hook子程,并且在窗口过程处理
    完消息之后调用WH_CALLWNDPROCRET Hook子程。  WH_CALLWNDPROCRET Hook传递指针到
    CWPRETSTRUCT结构,再传递到Hook子程。CWPRETSTRUCT结构包含了来自处理消息的窗口过程的
    返回值,同样也包括了与这个消息关联的消息参数。
    *)
 
end;
 
procedure StopMsg; stdcall;
begin
  UnhookWindowsHookEx(NextHook);
end;
 
initialization
 
FileMapHandle := OpenFileMapping(FILE_MAP_WRITE, false, _mapFile);
// Try to open an existing mapping file as MappingFileName specified
if FileMapHandle = 0 then // Not exist
  FileMapHandle := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0,
    sizeof(TShared), _mapFile);
// Here $FFFFFFFF is a invalid file handle, which cause this file being created in Windows page file.
 
if FileMapHandle = 0 then // Still unable to create a mapping file
  Exception.Create(
    'Unable to create shared memory. Make sure your system have enough memory and page file space.');
 
pShareMem := MapViewOfFile(FileMapHandle, FILE_MAP_WRITE or FILE_MAP_READ, 0,
  0, 0);
// Details of this API call, refer to MapViewOfFile in MSDN
if pShareMem = nil then // Create a pointer to the mapped file
begin
  CloseHandle(FileMapHandle);
  Exception.Create('Unable to map shared memory. Program halt.');
end;
 
 
// Whether HookHandle = 0 is used to judge if this hooked was installed
// In function StartHook, we will later give a value to HookHandle
 
finalization
 
UnMapViewOfFile(pShareMem);
CloseHandle(FileMapHandle);
 
end.
例子在delphi2010下编译成功。
Tagged