存档

‘学习笔记’ 分类的存档

绘制图象为什么会闪烁与双缓冲的作用

2011年12月15日 没有评论

1、显示的图形为什么会闪烁?

我们的绘图过程大多放在OnDraw或者OnPaint函数中,OnDraw在进行屏幕显示时是由OnPaint进行调用的。当窗口由于任何原因需 要重绘时,总是先用背景色将显示区清除,然后才调用OnPaint,而背景色往往与绘图内容反差很大,这样在短时间内背景色与显示图形的交替出现,使得显 示窗口看起来在闪。如果将背景刷设置成NULL,这样无论怎样重绘图形都不会闪了。当然,这样做会使得窗口的显示乱成一团,因为重绘时没有背景色对原来绘 制的图形进行清除,而又叠加上了新的图形。有的人会说,闪烁是因为绘图的速度太慢或者显示的图形太复杂造成的,其实这样说并不对,绘图的显示速度对闪烁的 影响不是根本性的。例如在OnDraw(CDC *pDC)中这样写:

pDC->MoveTo(0,0);
pDC->LineTo(100,100);

这个绘图过程应该是非常简单、非常快了吧,但是拉动窗口变化时还是会看见闪烁。其实从道理上讲,画图的过程越复杂越慢闪烁应该越少,因为绘图用的时 间与用背景清除屏幕所花的时间的比例越大人对闪烁的感觉会越不明显。比如:清楚屏幕时间为1s绘图时间也是为1s,这样在10s内的连续重画中就要闪烁5 次;如果清楚屏幕时间为1s不变,而绘图时间为9s,这样10s内的连续重画只会闪烁一次。这个也可以试验,在OnDraw(CDC *pDC)中这样写:
for(int i=0;i<100000;i++)
{
pDC->MoveTo(0,i);
pDC->LineTo(1000,i);
}
呵呵,程序有点变态,但是能说明问题。

说到这里可能又有人要说了,为什么一个简单图形看起来没有复杂图形那么闪呢?这是因为复杂图形占的面积大,重画时造成的反差比较大,所以感觉上要闪 得厉害一些,但是闪烁频率要低。那为什么动画的重画频率高,而看起来却不闪?这里,我就要再次强调了,闪烁是什么?闪烁就是反差,反差越大,闪烁越厉害。 因为动画的连续两个帧之间的差异很小所以看起来不闪。如果不信,可以在动画的每一帧中间加一张纯白的帧,不闪才怪呢。

2、如何避免闪烁

在知道图形显示闪烁的原因之后,对症下药就好办了。首先当然是去掉MFC提供的背景绘制过程了。实现的方法很多,
* 可以在窗口形成时给窗口的注册类的背景刷付NULL
* 也可以在形成以后修改背景
static CBrush brush(RGB(255,0,0));
SetClassLong(this->m_hWnd,GCL_HBRBACKGROUND,(LONG)(HBRUSH)brush);
* 要简单也可以重载OnEraseBkgnd(CDC* pDC)直接返回TRUE

这样背景没有了,结果图形显示的确不闪了,但是显示也象前面所说的一样,变得一团乱。怎么办?这就要用到双缓存的方法了。双缓冲就是除了在屏幕上有图形进行显示以外,在内存中也有图形在绘制。我们可以把要显示的图形先在内存中绘制好,然后再一次性的将内存中的图形按照一个点一个点地覆盖到屏幕上去(这个过程非常快,因为是非常规整的内存拷贝)。这样在内存中绘图时,随便用什么反差大的背景色进行清除都不会闪,因为看不见。当贴到屏幕上时,因为内存中最终的图形与屏幕显示图形差别很小(如果没有运动,当然就没有差别),这样看起来就不会闪。

分类: 全部文章, 学习笔记 标签:

flash版本更新导致shopex后台上传图片无效的问题

2011年11月15日 没有评论

4.8.4~4.8.5版本好像都有这个问题,下面是官方bbs上找到的补丁包,通过ftp上传覆盖就行了

文件清单
文件名          文件路径:                                  说明
component.js    shopadmin\js\package\component.js           JS文件-替换
uploader.swf    shopadmin\images\uploader.swf               flash文件-新增
frame.html      core\admin\view\product\detail\frame.html   商品图片上传-替换
list.html       core\admin\view\system\template\list.html   模板上传-替换
uploader.html   core\admin\view\system\tools\ uploader.html 上传按钮-替换

flash10.1兼容文件

分类: 全部文章, 学习笔记 标签:

解决bluehost主机同域邮件无法发送的问题

2011年11月9日 没有评论

bluehost主机,用php自带的mail函数给同域的邮件发送邮件的时候会有个问题,比如我的域名是anfirst.com,如果给info@anfirst.com就会失败,原因很简单,因为bluehost本身自带了smtp服务,如果给同域名的邮箱发送邮件,bluehost就错误的以为这个邮箱的服务器就是localhost,即使这个域名的真实mx记录不是这台服务器。
解决办法也很简单,我们要修改bluehost的默认配置。
在cpanel配置面板,从mail下面的mx entry下面进去,从上面的下拉框里选择相应域名,再下面的 MX (Mail Exchanger) 项,点击下面的小小的more链接

在出现的单选列表中,选择 Remote Mail Exchanger 点击change按钮保存。

到此为止,这个问题就已经解决了

shopex中集成的站长统计功能简单分析

2011年8月2日 没有评论

shopex中集成了一键开启站长统计功能,而无需去CNZZ注册,在phpcms,phpwind等中也都有类似的功能,下面是对这个功能的简单分析,以后也可以偷偷用在自己的网站中,呵呵。

<?php
//我们的域名,这里可以不唯一的
$domain = 'localhost';
//这个应该是CNZZ授权给shopex的加密密钥,如果错了就不能快捷申请账号
$encodestr = 'A34dfwfF';
//这个就是CNZZ授权给shopex的快捷申请账号的URL地址
$url = 'http://wss.cnzz.com/user/companion/shopex.php?domain='.$domain.'&key='.md5($domain.$encodestr);
//获取网页内容得到这样的一个字符串 80772914@3780692425
$res = file_get_contents($url);
//左边是CNZZ统计的站点id,右边是密码
$res = explode('@',$res);
//登录到CNZZ统计的URL,把下面的地址复制到地址栏就可以看到效果了
//http://wss.cnzz.com/user/companion/shopex_login.php?site_id=80772914&password=3780692425
//会自动跳转到 http://wss.cnzz.com/v1/main.php?siteid=80772914&s=main_stat
$login = 'http://wss.cnzz.com/user/companion/shopex_login.php?site_id='.$res[0].'&password='.$res[1];
header("Location:$login");

php pdo中bindParam() 和 bindValue()方法的区别

2011年7月27日 没有评论

方法 bindParam() 和 bindValue() 非常相似。
唯一的区别就是前者使用一个PHP变量绑定参数,而后者使用一个值。

所以使用bindParam是第二个参数只能用变量名,而不能用变量值,而bindValue至可以使用具体值。

$stm = $pdo->prepare("select * from users where user = :user");
$user = "jack";
//正确
$stm->bindParam(":user",$user);
//错误
//$stm->bindParam(":user","jack");
//正确
$stm->bindValue(":user",$user);
//正确
$stm->bindValue(":user","jack");

另外在存储过程中,bindParam可以绑定为input/output变量,如下面:

$stm = $pdo->prepare("call func(:param1)");
$param1 = "abcd";
$stm->bindParam(":param1",$param1); //正确
$stm->execute();

存储过程执行过后的结果可以直接反应到变量上。

对于那些内存中的大数据块参数,处于性能的考虑,应优先使用前者。

php截取html字符串,并自动补全html代码

2011年6月18日 没有评论

实际开发中会经常碰到,很多人直接先strip_tags过滤掉html标签,但是就只剩下纯文本了,可读性非常差,下面是一个函数

/**
 * 截取HTML,并自动补全闭合
 * @param $html
 * @param $length
 * @param $end
 */
function subHtml($html,$length) {
 $result = '';
 $tagStack = array();
 $len = 0;

 $contents = preg_split("~(<[^>]+?>)~si",$html, -1,PREG_SPLIT_NO_EMPTY| PREG_SPLIT_DELIM_CAPTURE);
 foreach($contents as $tag)
 {
 if (trim($tag)=="")  continue;
 if(preg_match("~<([a-z0-9]+)[^/>]*?/>~si",$tag)){
 $result .= $tag;
 }else if(preg_match("~</([a-z0-9]+)[^/>]*?>~si",$tag,$match)){
 if($tagStack[count($tagStack)-1] == $match[1]){
 array_pop($tagStack);
 $result .= $tag;
 }
 }else if(preg_match("~<([a-z0-9]+)[^/>]*?>~si",$tag,$match)){
 array_push($tagStack,$match[1]);
 $result .= $tag;
 }else if(preg_match("~<!--.*?-->~si",$tag)){
 $result .= $tag;
 }else{
 if($len + mstrlen($tag) < $length){
 $result .= $tag;
 $len += mstrlen($tag);
 }else {
 $str = msubstr($tag,0,$length-$len+1);
 $result .= $str;
 break;
 }

 }
 }
 while(!empty($tagStack)){
 $result .= '</'.array_pop($tagStack).'>';
 }
 return  $result;
}

/**
 * 截取中文字符串
 * @param $string 字符串
 * @param $start 起始位
 * @param $length 长度
 * @param $charset  编码
 * @param $dot 附加字串
 */
function msubstr($string, $start, $length,$dot='',$charset = 'UTF-8') {
 $string = str_replace(array('&amp;', '&quot;', '&lt;', '&gt;','&nbsp;'), array('&', '"', '<', '>',' '), $string);
 if(strlen($string) <= $length) {
 return $string;
 }

 if(strtolower($charset) == 'utf-8') {
 $n = $tn = $noc = 0;
 while($n < strlen($string)) {
 $t = ord($string[$n]);
 if($t == 9 || $t == 10 || (32 <= $t && $t <= 126)) {
 $tn = 1; $n++;
 } elseif(194 <= $t && $t <= 223) {
 $tn = 2; $n += 2;
 } elseif(224 <= $t && $t <= 239) {
 $tn = 3; $n += 3;
 } elseif(240 <= $t && $t <= 247) {
 $tn = 4; $n += 4;
 } elseif(248 <= $t && $t <= 251) {
 $tn = 5; $n += 5;
 } elseif($t == 252 || $t == 253) {
 $tn = 6; $n += 6;
 } else {
 $n++;
 }
 $noc++;
 if($noc >= $length) {
 break;
 }
 }
 if($noc > $length) {
 $n -= $tn;
 }
 $strcut = substr($string, 0, $n);
 } else {
 for($i = 0; $i < $length; $i++) {
 $strcut .= ord($string[$i]) > 127 ? $string[$i].$string[++$i] : $string[$i];
 }
 }

 return $strcut.$dot;
}

/**
 * 取得字符串的长度,包括中英文。
 */
function mstrlen($str,$charset = 'UTF-8'){
 if (function_exists('mb_substr')) {
 $length=mb_strlen($str,$charset);
 } elseif (function_exists('iconv_substr')) {
 $length=iconv_strlen($str,$charset);
 } else {
 preg_match_all("/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xef][\x80-\xbf][\x80-\xbf]|\xf0[\x90-\xbf][\x80-\xbf][\x80-\xbf]|[\xf1-\xf7][\x80-\xbf][\x80-\xbf][\x80-\xbf]/", $text, $ar); 
 $length=count($ar[0]);
 }
 return $length;
}

巧用金山快盘搭建多地可用的SVN”服务器”

2011年5月5日 没有评论

这里说的SVN服务器,并不是一个真正的服务器,却具有svn服务器的功能。因为有些代码在家里和公司都需要维护,代码的同步变得有些麻烦,一开始用了google code,孰料google被狙,gogole account都登陆不上了,经过研究,发现了一个利用金山快盘搭建svn服务器的功能。

客户端用TortoiseSVN,其实TortoiseSVN不仅仅是个SVN客户端,还集成了一些svn服务器进行版本库管理的功能。在金山快盘里建立一个文件夹svn,在svn目录再建立一个空文件夹 project,在此文件夹上点右键,在弹出菜单中的TortoiseSvn下执行”在此创建版本库”命令。这样版本库就创建在了快盘上,以后版本库任意的改动,金山网盘都会帮我们自动同步到各台电脑上,当然前提是这些电脑都是开启了使用同一个账户的快盘。

版本库建好了,就相当于我们在每台有快盘的机器上都有个SVN服务器端,只是这里的版本库URL设置成版本库的位置 file:///X:/svn/project,这时就可以从TortoiseSVN里检出(checkout),提交(commit),和更新(update)了,这样我在公司修改了代码,提交以后,金山快盘会帮我把版本库文件同步到家里的电脑上,回到家里我只需要update一下,就可以看到在公司修改后的代码了。

顺便帮金山坐下广告,申请金山快盘的地址是:http://k.wps.cn/register/

使用netbox把asp网站打包成本地运行的可执行程序

2011年4月26日 没有评论

netbox相当于一个超级精简的IIS,按照其官方的说法是“NetBox 提供 Microsoft IIS 5.0 兼容的 Active Server Pages 模块,不用修改代码直接将已经存在的使用 ASP 开发的应用程序移植到 NetBox 平台上来”,程序下载 http://www.netbox.cn:88/download/index.htm

安装完成后,使用非常简单,下面是个小例子

建立一个文件夹 wwwroot,把asp网站的程序和数据库等文件放在这里,相当于是网站的根目录

与wwwroot同级目录建立一个main.box文本文件,内容如下

Dim httpd

Shell.Service.RunService “NBWeb”, “NetBox Web Server”, “NetBox Http Server Sample”

‘———————- Service Event ———————

Sub OnServiceStart()
Set httpd = NetBox.CreateObject(“NetBox.HttpServer”)

If httpd.Create(“”, 8080) = 0 Then
Set host = httpd.AddHost(“”, “\wwwroot”)

host.EnableScript = true

‘———————-默认首页文件定义
host.AddDefault “index.asp”
host.AddDefault “default.asp”
host.AddDefault “default.htm”

httpd.Start

‘——–下面这里是定义运行exe文件后直接打开一个网页窗口,可以不要,直接在浏览器通过地址打开
Set htWin= CreateObject(“NetBox.HtmlWindow”)
htWin.ContextMenu=false
htWin.AllowClose=true
htWin.Width=723
htWin.Height=584
htWin.Title=”华康名家私8周年店庆抽奖系统”
htWin.scrollbar=false
htWin.Open “http://127.0.0.1:8080/”
htWin.ShowDialog

else
Shell.Quit 0
end if
End Sub

Sub OnServiceStop()
httpd.Close
‘Shell.Quit 0
End Sub

Sub OnServicePause()
httpd.Stop
End Sub

Sub OnServiceResume()
httpd.Start
End Sub

 

再建立的main.box文件上右键,build,生成exe文件,运行之即可

dell 1400-n 刷带SLIC2.1的BIOS 修改服务编号 从U盘安装win7系统 免激活

2011年4月24日 没有评论

本子是dell 1400-n系列,在换了CPU,加了内存过后的配置如下,酷睿2双核T7800,DDR2800 2.5G,显卡是965主板集成的intel X3100,其他的对系统性能基本没影响的,就不罗列了。

安装win7分为如下几个步骤。

一、刷bios,刷成带slic2.1的,下载个程序运行之即可,会自动重启机器,自动刷好bios的。修改过的带SLIC2.1的A09版bios下载 。参考这篇文章 bios下载链接也在里面   http://dell.benyouhui.it168.com/thread-988687-1-1.html

二、修改机器的服务编号,因为我这个型号预装的是linux,本身是不预装windows系统的,而戴尔的bios就是根据主板的服务编号来判断是否开启slic2.1的,如果服务编号不对,及时刷成袋SLIC2.1的bios也是没用的, 用SLIC Dump ToolKit(可以自己搜索下载) 这个软件可以查看slic2.1信息是否有效。

要修改服务编号,需要用到一个工具,听说是DELL的内部工具,SvctagV3.4(可以自己搜索下载)。这个工具需要在纯DOS环境下运行,这时候就需要用U盘坐一个启动盘既可,制作启动DOS启动U盘 可以参考这篇文章 http://hi.baidu.com/nnffnn/blog/item/6158a635d857588ba71e1271.html,做好启动盘,把SvctagV3.4这个软件解压后,放到U盘,重新启动时设置从U盘启动,进入dos界面

svctag.exe 回车
Y   回车
输入服务编号(随便找个带预装windows的机器的服务编号就行了,例如 HKNV82X

到这一步,如果用SLIC Dump ToolKit,应该就显示slic2.1提取成功了,到这里机器已经可以像dell带预装系统的机器一样可以按照oem版本的win7了。

三、安装戴尔oem版的,windows7操作系统。

32位win7链接:ed2k://|file|Dell_Win7_U_32bit_CN.iso|2625847296|54ebc1d4bb4a34e7faf3ce133af22ba7|h=5qjyndhto7si7lqv56bm5enxbowoxihc|/

64位win7链ed2k://|file|Dell_Win7_U_64bit_CN.iso|3362775040|355b7386addf624645ef6b64689a40b9|h=akz6e6gwlwdl3ivrfkjugy5ts5ne43g4|/

下载后,我是从再制作个U盘安装盘,用这个工具轻松制作 Windows 7 USB/DVD Download Tool,注意保存U盘数据哦,因为会重新格式化U盘。重启机器,设置成U盘启动,就可以像从光盘安装一样了。

安装好过后,就免激活,直接正版!

分类: 学习笔记, 生活点滴 标签:

php压缩/解压zip的利器-PclZip

2011年3月31日 没有评论

PclZip简介与使用

PclZip介绍
PclZip library能够压缩与解压缩Zip格式的压缩档(WinZip、PKZIP);且能对此类类档案进行处理,包括产生压缩档、列出压缩档的内容以及解压缩档案等等。由于能够在伺服器端进行压缩与解压缩的动作,所以相当方便使用。
PclZip定义一个PclZip类别,其类别物件可视为一个ZIP档案,亦提供method来进行处理。

如何使用PclZip
1.基础
所有的功能都由pclzip.lib.php这个档案提供,PclZip library可于其首页(www.phpconcept.net/pclzip/index.en.php)下载。所有的PKZIP档案其实就是一个PclZip的类别物件。当产生一个PclZip档案(ie, PclZip类别物件),就会先产生一个压缩档,且档名已经指定,但此压缩档的内容尚未存在:

< ?PHP
require_once('pclzip.lib.php');
$archive = new PclZip("archive.zip");
?>

此物件提供了一些public method可用来处理此档案。

2.参数
每一个method有其各自可使用的参数,包括有必须与非必须的参数:

< ?PHP
require_once('pclzip.lib.php');
$archive = new PclZip('archive.zip');

$v_list = $archive->add('dev/file.txt',
PCLZIP_OPT_REMOVE_PATH, 'dev');
?>

上例中的’dev/file.txt’就是必须参数;’PCLZIP_OPT_REMOVE_PATH’则为非必须参数。当然有些method也可以只包含非必须的参数:

< ?PHP
$list = $archive->extract(PCLZIP_OPT_PATH, "folder",
PCLZIP_OPT_REMOVE_PATH, "data",
PCLZIP_CB_PRE_EXTRACT, "callback_pre_extract",);
?>

上例中原本压缩档内档案存放的路径为/data,不过你可以指定解压缩至/folder中。此外,在解压缩之前,会呼叫callback function(’callback_pre_extract()’),此function可让使用者在解压缩的过程中变更档案存放路径与档名,或是选择某些档案不解压缩。
所有可用的非必要参数可参考网址(www.phpconcept.net/pclzip/man/en/index.php)。

3.回传值
每个method所回传的值可能会不同,将会在每个method中说明。不过大部分的method回传0、error或是阵列。

4.错误处理
从版本1.3之后,错误处理已经整合至PclZip类别中,当一个method回传错误码,可以得知一些额外的讯息以方便错误处理:
* errorName():回传错误名称
* errorCode():回传错误码
* errorInfo():回传错误的描述

接下来会举几个例子来说明如何使用PclZip。

PclZip实例1、产生ZIP压缩档
PclZip($zipname):为PclZip constructor,$zipname为PKZIP压缩档的档名。
主要是产生一个PclZip物件,即一个PKZIP压缩档;但此时,只有压缩档产生出来,并做一些检查(例如是否有开启zlib extension…等),除此之外,并没有做其他动作。
create($filelist, [optional arguments list]):将参数$filelist指定的档案或目录(包含当中所有档案与子目录)加入上述所产生的压缩档中。
而非必要的参数则能够修改压缩档内的档案存放路径。
此method可用的参数可以参考网志(www.phpconcept.net/pclzip/man/en/index.php)。

下面的示例说明如何产生PKZIP压缩档(档名为archive.zip),并将file.txt、data/text.txt以及目录folder(包含当中的档案与子目录)加入刚刚产生的archive.zip中:

< ?PHP
include_once('pclzip.lib.php');
$archive = new PclZip('archive.zip');
$v_list = $archive->create('file.txt,data/text.txt,folder');
if ($v_list == 0) {
die("Error : ".$archive->errorInfo(true));
}
?>

下面的示例说明基本上与上例一样产生archive.zip,但在将file.txt与text.txt压缩于其中时,将路径由data/改为install/ ;因此,在archive.zip中这两个档案的路径会是install/file.txt与install/text.txt

< ?PHP
include_once('pclzip.lib.php');
$archive = new PclZip('archive.zip');
$v_list = $archive->create('data/file.txt,data/text.txt',
PCLZIP_OPT_REMOVE_PATH, 'data',
PCLZIP_OPT_ADD_PATH, 'install');
if ($v_list == 0) {
die("Error : ".$archive->errorInfo(true));
}
?>

PclZip实例2、列出压缩档内容
listContent( ) :列出压缩档中的内容,包括档案的属性与目录:

< ?PHP
include_once('pclzip.lib.php');
$zip = new PclZip("test.zip");

if (($list = $zip->listContent()) == 0) {
die("Error : ".$zip->errorInfo(true));
}

for ($i=0; $i<sizeof ($list); $i++) {
for(reset($list[$i]); $key = key($list[$i]); next($list[$i])) {
echo "File $i / [$key] = ".$list[$i][$key]."<br>";
}
echo "<br />";
}
?></sizeof>

上例将会回传结果:
File 0 / [filename] = data/file1.txt
File 0 / [stored_filename] = data/file1.txt
File 0 / [size] = 53
File 0 / [compressed_size] = 36
File 0 / [mtime] = 1010440428
File 0 / [comment] =
File 0 / [folder] = 0
File 0 / [index] = 0
File 0 / [status] = ok

File 1 / [filename] = data/file2.txt
File 1 / [stored_filename] = data/file2.txt
File 1 / [size] = 54
File 1 / [compressed_size] = 53
File 1 / [mtime] = 1011197724
File 1 / [comment] =
File 1 / [folder] = 0
File 1 / [index] = 1
File 1 / [status] = ok

PclZip实例3、解压缩档案
extract([options list]) :解压缩PKZIP中的档案或目录。
[options list]可用的参数可参考网址(www.phpconcept.net/pclzip/man/en/index.php)。这些参数能让使用者在解压缩的时候有更多的选项,譬如指定变更解压缩档案的路径、指定只解压缩某些档案或不解压缩某些档案或者是将档案解压缩成字串输出(可用于readme档)。

下例是一个简单的解压缩档案示例,将压缩档archive.zip内的档案解压缩至目前的目录:

< ?PHP
require_once('pclzip.lib.php');
$archive = new PclZip('archive.zip');

if ($archive->extract() == 0) {
die("Error : ".$archive->errorInfo(true));
}
?>

下例是进阶的解压缩档案使用,archive.zip中所有档案都解压缩于data/中,而特别指明在install/release中的所有档案也直接丢于data/中,而非data/install/ release:

< ?PHP
include('pclzip.lib.php');
$archive = new PclZip('archive.zip');
if ($archive->extract(PCLZIP_OPT_PATH, 'data',
PCLZIP_OPT_REMOVE_PATH, 'install/release') == 0) {
die("Error : ".$archive->errorInfo(true));
}
?>

本文转自 http://www.ccvita.com/59.html