存档

‘编程开发’ 分类的存档

cocoa恢复显示关闭的窗口

2011年11月25日 没有评论

在Mac OS中,点击窗口左上方的x,窗口将会关闭。如果你希望通过点击dock上的图标将窗口重新打开,你可以用如下方法做。

实现方法如下:

在delegate里设置一个outlet,比如myWindow:

IBOutlet NSWindow *myWindow;

在Interface Builder中,将主窗口的”Release When Closed”选项取消掉。再将delegate里的myWindow和你的主窗口连接起来,然后在delegate里实现如下方法:

- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag

{

if (flag) {

return NO;

}

else

{

[myWindow makeKeyAndOrderFront:self];

return YES;

}

}

这样窗口即使被关闭,也可以点击dock上的图标重新恢复显示。

分类: 编程开发 标签:

ObjC: 委托模式

2011年9月9日 没有评论

在ObjC中,经常提到委托模式(delegate),非常重要。比如官方交互API,委托模式使用的很常见,比如UIView的 setAnimationDelegate,设置动画的委托。不理解委托模式,就不能很快的理解很多API的使用,因为它们使用一样的模式,了解这个模 式,就会心领神会,立即上手。

下面用通俗的话说说委托模式是干什么用的。实际上ObjC中的委托模式,类似于Java中的回调(CallBack)机制,或者说监听器机制。再或 者说,类似JavaScript语言里面的onclick事件和函数的作用。比如要实现点击一个按钮之后做什么事情,这里肯定有个视图类,有个控制类,无论你是使用什么语言和开发工具。视图类能知道用户什么时候点击了按钮,但是不知道点击了以后做什么,控制类知道点击按钮后做什么,而不知道何时用户会点击。那么,可以将控制类委托给视图类,当点击的时候视图类调用控制类。

如果使用过Java的Swing等做本地图形界面开发,应该知道在视图类中包含了大量的(匿名)内部类,或者要注册监听器,这些机制起到和ObjC委托类似的功效。可以这样理解:监听器、(匿名)内部类是实现怎么做的部分,但是不知道何时会发生事情,视图类在事件发送时调用监听器、(匿名)内部类,视图类是知道何时发生事情的。

写个简单的示例,是在main方法里写的,模拟一下委托在视图和控制中的作用。这里面,我有一个屏幕(Screen)类,就把它当视图吧。需求是当点击屏幕的时候爆炸。那么我有个动作(Action)类,它会实现爆炸动作。

 

用协议实现委托模式

下面的代码写的很生硬,后面会逐渐演化为合理的实现。第一个示例只是想说明技术上如何实现,没有实际运用上的意义。

这里因为是模拟,可以把main方法看作是用户再操作界面,通过点击创建了个视图(Screen),然后调用Screen的实例方法onTouch,这里模拟用户用手点击了屏幕:

#import <Foundation/Foundation.h>
#import “Screen.h”

int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

Screen *screen=[[Screen alloc] init];
screen.delegate=screen;

[screen onTouch];

[screen release];

[pool drain];
return 0;
}

 

这里先不用管:

screen.delegate=screen;

后面再说。

Action类,在这里用协议来实现:

#import <Cocoa/Cocoa.h>

@protocol Action <NSObject>

- (void) doAction;

@end

 

是一个协议,该协议继承了NSObject协议。这里要注意,NSObject在这里不是类,确实有同名类。这个协议定义了一个doAction方法,这个方法可实现比如“屏幕爆炸”的需求。

下面说说屏幕(Screen)类,头文件:

#import <Foundation/Foundation.h>
#import “Action.h”

@interface Screen : NSObject <Action> {
id <Action> delegate;
}

@property(nonatomic,retain) id <Action> delegate;

- (void) onTouch;

@end

 

这里的onTouch方法,就是模拟Screen被用户点击后调用的方法。Screen类实现了Action协议。然后它还有个Action类型的成员delegate。为了能设置delegate实例变量,还为它设置了property。

下面看看实现文件:

#import “Screen.h”

@implementation Screen

@synthesize delegate;

- (void) onTouch{
NSLog(@”on touch …”);
if ([delegate conformsToProtocol:@protocol(Action)] &&
[delegate respondsToSelector:@selector(doAction)]) {
[delegate performSelector:@selector(doAction)];
}
NSLog(@”on touched.”);
}

- (void) doAction{
NSLog(@”Bang!!!!!!!!!”);
}

@end

 

这里重点看onTouch方法内部代码,要判断delegate是否是Action协议,而且是否有doAction方法,这个判断够严谨了。如果正确,就调用Action协议的doAction方法。

实际上未必要让Screen实现Action协议,虽然开发中经常是类似这样的做法。任意的实现Action协议的类实例都可以设置给screen的delegate属性。

上面的示例和开发中碰到的情况不很像,实际情况往往类似下面示例的样子。首先看看main方法:

#import <Foundation/Foundation.h>
#import “MyScreen.h”

int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

Screen *screen=[[MyScreen alloc] init];

[screen onTouch];

[screen release];

[pool drain];
return 0;
}

 

这里发现增加了个MyScreen 类。它继承自Screen类。这里的代码不再设置delegate属性,因为已经在MyScreen类的init方法中设置了。后面会看到。

Action协议没有变化,只是增加了optional:

#import <Cocoa/Cocoa.h>

@protocol Action <NSObject>

@optional
- (void) doAction;

@end

Screen类,可以看作抽象类,它主要供继承使用,来复用委托模式的代码。头文件:

#import <Foundation/Foundation.h>
#import “Action.h”

@interface Screen : NSObject <Action> {
id <Action> delegate;
}

@property(nonatomic,retain) id <Action> delegate;

- (void) onTouch;

@end

 

实现文件:

#import “Screen.h”

@implementation Screen

@synthesize delegate;

- (void) onTouch{
NSLog(@”on touch …”);
if ([delegate conformsToProtocol:@protocol(Action)] &&
[delegate respondsToSelector:@selector(doAction)]) {
[delegate performSelector:@selector(doAction)];
}
NSLog(@”on touched.”);
}

@end

这里不再实现doAction方法。

下面看MyScreen类的头文件:

#import <Cocoa/Cocoa.h>
#import “Screen.h”

@interface MyScreen : Screen {

}

@end

 

MyScreen类的实现文件:

#import “MyScreen.h”

@implementation MyScreen

- (id) init{
if (self=[super init]) {
delegate=self;
}
return self;
}

- (void) doAction{
NSLog(@”Bang!!!!!!!!!”);
}

@end

 

用类别实现委托模式

可以使用类别(Category)实现委托模式。还是上面的例子。下面使用Category实现了个示例。

main方法:

int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

Screen *screen=[[Screen alloc] init];

[screen onTouch];

[screen release];

[pool drain];
return 0;
}

 

Screen类的头文件:

#import <Foundation/Foundation.h>

@interface Screen : NSObject {
id delegate;
}

@property(nonatomic,retain) id delegate;

- (void) onTouch;

@end

 

在这个示例中,实际上property没有起什么作用。

实现文件:

#import “Screen.h”

@implementation Screen

@synthesize delegate;

- (id) init{
if (self=[super init]) {
delegate=self;
}
return self;
}

- (void) onTouch{
NSLog(@”on touch …”);
if ([delegate respondsToSelector:@selector(doAction)]) {
[delegate performSelector:@selector(doAction)];
}
NSLog(@”on touched.”);
}

@end

 

写到这里,如果运行代码,只会打印类似下面的日志:

2011-05-26 10:37:30.843 DelegateDemo[5853:a0f] on touch …
2011-05-26 10:37:30.846 DelegateDemo[5853:a0f] on touched.

下面写Category代码,名称为ScreenAction,它的头文件:

#import <Cocoa/Cocoa.h>
#import “Screen.h”

@interface Screen (ScreenAction)

- (void) doAction;

@end

 

实现文件:

#import “ScreenAction.h”

@implementation Screen (ScreenAction)

- (void) doAction{
NSLog(@”BANG!!!!!!”);
}

@end

 

实现了这部分代码再执行:

2011-05-26 10:37:30.843 DelegateDemo[5853:a0f] on touch …
2011-05-26 10:37:30.846 DelegateDemo[5853:a0f] BANG!!!!!!
2011-05-26 10:37:30.846 DelegateDemo[5853:a0f] on touched.

分类: 编程开发 标签:

给自定义控件.ascx传参数并传值

2011年7月7日 没有评论

在控件.cs声明控件属性

private int _RoomID = 0;

public int RoomID
{
get { return _RoomID; }
set { _RoomID= value; }
}
在aspx页面

<uc1:TC ID=”TID” runat=”server” RoomID=”100″ />

这样便可以给想要传参数的控件传参数传值

分类: 编程开发 标签:

PNG背景图片在IE6不透明及链接失效怎么办

2011年6月20日 没有评论

有时需要在网页中用到一些透明背景图片,对效果要求不高的用GIF图片即可。但对于有透 明度、阴影、发光等效果的,PNG图片就比GIF图片更有优势。但目前只有Firefox、Opera、IE7这三款浏览器对PNG图片支持得比较好,我 们常用的IE6.0却不支持透明的PNG图片,因此要让PNG透明背景图片在IE6.0 中正确显示,只能在CSS里用滤镜来解决了。具体CSS如下:

<style>
.but{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=images/buts_03.png); background:url(buts_03.png) no-repeat!important;background:none; width:100px; height:200px;}
</style>

另外,用了这个滤镜以后,会发现链接失效了。此时需要在a标签里加上position:relative;代码,即:
<div><a href=”http://www.mini88s.com” style=”position:relative;”>文字或图片</a></div>

或者可以在链接外面再加一个div,即:
<div ><div style=”position:relative;”><a href=”http://www.mini88s.com”>文字或图片</a></div></div>

分类: 编程开发 标签:

javascript 页面对象获取:getElementByID,getElementsByName,getElementsByTagName

2011年6月14日 没有评论

getElementByID getElementsByName getElementsByTagName的区别和总结
WEB标准下可以通过getElementById(), getElementsByName(), and getElementsByTagName()访问DOCUMENT中的任一个标签:

1、getElementById()
getElementById()可以访问DOCUMENT中的某一特定元素,顾名思义,就是通过ID来取得元素,所以只能访问设置了ID的元素。
比如说有一个DIV的ID为docid:
<div id=”docid”></div>
那么就可以用getElementById(“docid”)来获得这个元素。

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”
http://www.w3.org/TR/html4/loose.dtd“>
<html>
<head>
< http-equiv=”Content-Type” content=”text/html; charset=gb2312″>
<title>ById</title>
<style type=”text/css”>
<!–
#docid{
height:400px;
width:400px;
background-color:#999;}
–>
</style>
</head>
<body><div id=”docid” name=”docname” =”bgcolor()”></div>
</body>
</html>
< language=”Java” type=”text/Java”>
<!–
bgcolor(){
getElementById(“docid”).style.backgroundColor=”#000″
}
–>
</>
、getElementsByName()
这个是通过NAME来获得元素,但不知大家注意没有,这个是GET ELEMENTS,复数ELEMENTS代表获得的不是一个元素,为什么呢?
因为DOCUMENT中每一个元素的ID是唯一的,但NAME却可以重复。打个比喻就像人的身份证号是唯一的(理论上,虽然现实中有重复),但名字

重复的却很多。如果一个文档中有两个以上的标签NAME相同,那么getElementsByName()就可以取得这些元素组成一个数组。

比如有两个DIV:
<div name=”docname” id=”docid1″></div>
<div name=”docname” id=”docid2″></div>
那么可以用getElementsByName(“docname”)获得这两个DIV,用getElementsByName(“docname”)[0]访问第一个DIV,用getElementsByName
3、getElementsByTagName()
这个呢就是通过TAGNAME(标签名称)来获得元素,一个DOCUMENT中当然会有相同的标签,所以这个方法也是取得一个数组。
下面这个例子有两个DIV,可以用getElementsByTagName(“div”)来访问它们,用getElementsByTagName(“div”)[0]访问第一个DIV,用

getElementsByTagName(“div”)[1]访问第二个DIV。

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd“>
<html xmlns=”http://www.w3.org/1999/xhtml“>
<head>
< http-equiv=”Content-Type” content=”text/html; charset=gb2312″>
<title>Byname,tag</title>
<style type=”text/css”>
<!–
#docid1,#docid2{
margin:10px;
height:400px;
width:400px;
background-color:#999;}
–>
</style>
</head>
<body>
<div name=”docname” id=”docid1″ =”bgcolor()”></div>
<div name=”docname” id=”docid2″ =”bgcolor()”></div>
</body>
</html>
< language=”Java” type=”text/Java”>
<!–
bgcolor(){
var docnObj=getElementsByTagName(“div”);
docnObj[0].style.backgroundColor = “black”;
docnObj[1].style.backgroundColor = “black”;
}
–>
</>
总结一下标准DOM,访问某一特定元素尽量用标准的getElementById(),访问标签用标准的getElementByTagName(),但IE不支持

getElementsByName(),所以就要避免使用getElementsByName(),但getElementsByName()和不符合标准的all[]也不是全无是处,它

们有自己的方便之处,用不用那就看网站的用户使用什么浏览器,由你自己决定了。

Java中的getElementById十分常用,但在标准的页面中,一个id只能出现一次,如果我想同时控制多个元素,例如点一个 链接, 让多个层隐藏,该怎么做?用class,当然,同一个class是可以允许在页面中重复出现的,那么有没有getElementByClass呢?没有, 但是可以解决:

//Create an array
var allPageTags = new Array();

hideDivWithClasses(theClass) {
//Populate the array with all the page tags
var allPageTags=getElementsByTagName(“div”);
//Cycle through the tags using a for loop
for (i=0; i//Pick out the tags with our class name
if (allPageTags[i].className==theClass) {
//Manipulate this in whatever way you want
allPageTags[i].style.display=’none’;
}
}
}

1,grid.getCell(i,3).innerHTML;curobj.nextSibling.innerHTML

innerHTML InnerHtml 属性不自动对进出 HTML 实体的特殊字符进行编码。HTML 实体允许显示特殊字符(如 < 字符),浏览器通常会将这些字符解释为具有特殊含义。< 字符会被解释为标志的开头,并且不会在页面上显示。若要显示 < 字符,将需要使用实体 &lt;。

例如,如果 InnerHtml 属性设置为 “<b> Hello </b>”,则 < 和 > 字符不会分别转换为 &lt; 和 &gt;。呈现的输出仍将是:<b> Hello </b>。浏览器将检测 <b> 标记并用粗体显示“Hello”文本。

警告   由于未对此文本进行 HTML 编码,因此可以在文本的 HTML 标记内嵌入脚本。如果该属性是使用用户输入动态设置的,请务必验证它的值以减少安全漏洞。
若要提供自动 HTML 编码和解码,请使用 InnerText 属性。

以上是微软的一个网站上介绍的,而我只是简单的认为取出来的是html格式。
2,typeName = temp.options[temp.selectedIndex].innerText;all(“B1″).innerText=”关闭”;name ==name_other.options[i].innerText;opn.innerText=nameArray[i];

使用 InnerText 属性以编程方式修改 HTML 服务器控件的开始和结束标记之间的内容。

与 InnerHtml 属性不同,InnerText 属性自动对进出 HTML 实体的特殊字符进行编码。HTML 实体允许显示特殊字符(如 < 字符),浏览器通常会将这些字符解释为具有特殊含义。< 字符会被解释为标志的开头,并且不会在页面上显示。若要显示 < 字符,将需要使用实体 &lt;。

例如,如果 InnerText 属性设置为 “<b> Hello </b>”,则 < 和 > 符号分别转换为 &lt; 和 &gt;。呈现的输出将是:&lt; b &gt; Hello &lt;/b &gt;。&lt; 和 &gt; 实体将向浏览器指示这些字符将显示在页上。浏览器将不检测 <b> 标记并用粗体显示该文本。显示在页上的文本是:<b> Hello </b>。

若要放置自动 HTML 编码和解码,请使用 InnerHtml 属性。

分类: 编程开发 标签:

提高PHP编程效率的53个要点

2011年4月23日 没有评论

用单引号代替双引号来包含字符串,这样做会更快一些。因为PHP会在双引号包围的字符串中搜寻变量,单引号则不会,注意:只有echo能这么做,它是一种 可以把多个字符串当作参数的“函数”(译注:PHP手册中说echo是语言结构,不是真正的函数,故把函数加上了双引号)。
1、如果能将类的方法定义成static,就尽量定义成static,它的速度会提升将近4倍。
2、$row[’id’] 的速度是$row[id]的7倍。
3、echo 比 print 快,并且使用echo的多重参数(译注:指用逗号而不是句点)代替字符串连接,比如echo $str1,$str2。
4、在执行for循环之前确定最大循环数,不要每循环一次都计算最大值,最好运用foreach代替。
5、注销那些不用的变量尤其是大数组,以便释放内存。
6、尽量避免使用__get,__set,__autoload。
7、require_once()代价昂贵。
8、include文件时尽量使用绝对路径,因为它避免了PHP去include_path里查找文件的速度,解析操作系统路径所需的时间会更少。
9、如果你想知道脚本开始执行(译注:即服务器端收到客户端请求)的时刻,使用$_SERVER[‘REQUEST_TIME’]要好于time()。
10、函数代替正则表达式完成相同功能。
11、str_replace函数比preg_replace函数快,但strtr函数的效率是str_replace函数的四倍。
12、如果一个字符串替换函数,可接受数组或字符作为参数,并且参数长度不太长,那么可以考虑额外写一段替换代码,使得每次传递参数是一个字符,而不是只写一行代码接受数组作为查询和替换的参数。
13、使用选择分支语句(译注:即switch case)好于使用多个if,else if语句。
14、用@屏蔽错误消息的做法非常低效,极其低效。
15、打开apache的mod_deflate模块,可以提高网页的浏览速度。
16、数据库连接当使用完毕时应关掉,不要用长连接。
17、错误消息代价昂贵。
18、在方法中递增局部变量,速度是最快的。几乎与在函数中调用局部变量的速度相当。
19、递增一个全局变量要比递增一个局部变量慢2倍。
20、递增一个对象属性(如:$this->prop++)要比递增一个局部变量慢3倍。
21、递增一个未预定义的局部变量要比递增一个预定义的局部变量慢9至10倍。
22、仅定义一个局部变量而没在函数中调用它,同样会减慢速度(其程度相当于递增一个局部变量)。PHP大概会检查看是否存在全局变量。
23、方法调用看来与类中定义的方法的数量无关,因为我(在测试方法之前和之后都)添加了10个方法,但性能上没有变化。
24、派生类中的方法运行起来要快于在基类中定义的同样的方法。
25、调用带有一个参数的空函数,其花费的时间相当于执行7至8次的局部变量递增操作。类似的方法调用所花费的时间接近于15次的局部变量递增操作。
26、Apache解析一个PHP脚本的时间要比解析一个静态HTML页面慢2至10倍。尽量多用静态HTML页面,少用脚本。
27、除非脚本可以缓存,否则每次调用时都会重新编译一次。引入一套PHP缓存机制通常可以提升25%至100%的性能,以免除编译开销。
28、尽量做缓存,可使用memcached。memcached是一款高性能的内存对象缓存系统,可用来加速动态Web应用程序,减轻数据库负载。对运算码 (OP code)的缓存很有用,使得脚本不必为每个请求做重新编译。
29、当操作字符串并需要检验其长度是否满足某种要求时,你想当然地会使用strlen()函数。此函数执行起来相当快,因为它不做任何计算,只返回在 zval 结构(C的内置数据结构,用于存储PHP变量)中存储的已知字符串长度。但是,由于strlen()是函数,多多少少会有些慢,因为函数调用会经过诸多步 骤,如字母小写化(译注:指函数名小写化,PHP不区分函数名大小写)、哈希查找,会跟随被调用的函数一起执行。在某些情况下,你可以使用isset() 技巧加速执行你的代码。
(举例如下)
if (strlen($foo) < 5) { echo “Foo is too short”$$ }
(与下面的技巧做比较)
if (!isset($foo{5})) { echo “Foo is too short”$$ }
调用isset()恰巧比strlen()快,因为与后者不同的是,isset()作为一种语言结构,意味着它的执行不需要函数查找和字母小写化。也就是说,实际上在检验字符串长度的顶层代码中你没有花太多开销。
34、当执行变量$i的递增或递减时,$i++会比++$i慢一些。这种差异是PHP特有的,并不适用于其他语言,所以请不要修改你的C或Java代码并 指望它们能立即变快,没用的。++$i更快是因为它只需要3条指令(opcodes),$i++则需要4条指令。后置递增实际上会产生一个临时变量,这个 临时变量随后被递增。而前置递增直接在原值上递增。这是最优化处理的一种,正如Zend的PHP优化器所作的那样。牢记这个优化处理不失为一个好主意,因 为并不是所有的指令优化器都会做同样的优化处理,并且存在大量没有装配指令优化器的互联网服务提供商(ISPs)和服务器。
35、并不是事必面向对象(OOP),面向对象往往开销很大,每个方法和对象调用都会消耗很多内存。
36、并非要用类实现所有的数据结构,数组也很有用。
37、不要把方法细分得过多,仔细想想你真正打算重用的是哪些代码?
38、当你需要时,你总能把代码分解成方法。
39、尽量采用大量的PHP内置函数。
40、如果在代码中存在大量耗时的函数,你可以考虑用C扩展的方式实现它们。
41、评估检验(profile)你的代码。检验器会告诉你,代码的哪些部分消耗了多少时间。Xdebug调试器包含了检验程序,评估检验总体上可以显示出代码的瓶颈。
42、mod_zip可作为Apache模块,用来即时压缩你的数据,并可让数据传输量降低80%。
43、在可以用file_get_contents替代file、fopen、feof、fgets等系列方法的情况下,尽量用 file_get_contents,因为他的效率高得多!但是要注意file_get_contents在打开一个URL文件时候的PHP版本问题;
44、尽量的少进行文件操作,虽然PHP的文件操作效率也不低的;
45、优化Select SQL语句,在可能的情况下尽量少的进行Insert、Update操作(在update上,我被恶批过);
46、尽可能的使用PHP内部函数(但是我却为了找个PHP里面不存在的函数,浪费了本可以写出一个自定义函数的时间,经验问题啊!);
47、循环内部不要声明变量,尤其是大变量:对象(这好像不只是PHP里面要注意的问题吧?);
48、多维数组尽量不要循环嵌套赋值;
49、在可以用PHP内部字符串操作函数的情况下,不要用正则表达式;
50、foreach效率更高,尽量用foreach代替while和for循环;
51、用单引号替代双引号引用字符串;
52、“用i+=1代替i=i+1。符合c/c++的习惯,效率还高”;
53、对global变量,应该用完就unset()掉;

分类: 编程开发 标签:

pre中自动换行的问题

2011年2月27日 没有评论

本站文章中使用了 pre 格式输出 代码。 而浏览器默认是强制不换行输出 pre 里的内容。这样的话,代码一长就出现了撑到页面外部的样子。在之前我都是有意的在代码里强制换行… 累啊. 今天有意的google了下,找到了:

pre {
white-space: pre-wrap; /* css-3 */
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
white-space: -pre-wrap; /* Opera 4-6 */
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* Internet Explorer 5.5+ */
}

经测试,除IE[当前使用6] 外, 其他可以…. 郁闷,然后增加 width:600px; 后,ok,.换行了,其实位置还是衍生出去了。样子是这样的: 代码是在里面了,但下面的叙述性的东西却出了去。在说,定义一个这个宽度也不是个好的方法,其他的不直接改这个css的方法基本没有了。

然后看上面css想到, 为什么定义其他的都用 white-space 而定义 IE 的不使用呢? 又不是IE 不支持。。于是加上就可以了[翻了google的前5页, 没找到一个改css解决的...汗]。

 pre {
white-space: pre-wrap; /* css-3 */
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
white-space: -pre-wrap; /* Opera 4-6 */
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* Internet Explorer 5.5+ */
white-space : normal ;       /* Internet Explorer 5.5+ */
}

至于本站上使用的是把ie和其他的分开了,因为white-space 在最后也都作用于其他了….

pre {
 white-space: pre-wrap;       /* css-3 */
 white-space: -moz-pre-wrap;  /* Mozilla, since 1999 */
 white-space: -pre-wrap;      /* Opera 4-6 */
 white-space: -o-pre-wrap;    /* Opera 7 */
}
* html pre {
 word-wrap: break-word;       /* Internet Explorer 5.5+ */
 white-space : normal ;       /* Internet Explorer 5.5+ */
}
分类: 编程开发 标签:

Flash Builder 4 正式版破解注册方法(flex4)

2011年2月12日 没有评论

Flash Builder 4正式版发布,很高兴还有简体中文版,下载地址自己去Adobe官网上下吧。

关于破解,网上有很的注册序列号,但都已经过期了。

我们可以使用下面的注册机来生成序列号:

http://files.cnblogs.com/tintown/flashbuiler4keygen.rar

但是注册序列号第一次使用后,第二次打开时,会去adobe的官网验证序列号的有效性,所以,经常导致第二次打开FB时,会过期无效。

所以我们可以让adobe不去官网验证即可,方法如下:

在C:\WINDOWS\system32\drivers\etc\hosts文件中加入一条:
127.0.0.1 activate.adobe.com
再用注册机生成一个注册码,重新注册一下,重启之后不会再出现在注册试用提示了。



分类: 编程开发 标签:

最简单的PHP MVC留言本实例

2011年1月31日 1 条评论

写完那篇“写给懂C语言的人的PHP基本语法入门”后一直在学习PHP5的 OOP,目的很简单,就是想研究MVC的PHP实现,所以,兴趣很快转移到MVC上面,网上有很多长篇大论,但是看完了我还是不能写出一个最简单的MVC 程序,我这个人学东西有个习惯,那就是先要掌握一个最简单的“Hello World”,然后再以此为基础扩展开去,否则心里没底,一头雾水。
经过一番搜索,找到了一篇翻译文章(作者:Harry Fuecks 翻译:Easy Chen URL:http://www.21ds.net/article/4/453 原文URL:http://www.phppatterns.com/docs/ … _controller_pattern)作者以商品目录浏览为例,给出了完整的MVC架构代码。仔细一看,发现他的C和V是继承关系,耦合很紧,似乎不是很理想,但马上又看到了作者的第二个版本(http://www.phppatterns.com/doku.php/design/mvc_pattern_version_2),这个版本的C和V分离得比较清楚,仔细研读了这个版本,然后仿照着实现了一个留言板。
标题上我把这个留言板叫最简单的,其实应该叫最简陋的,因为把全部注意力集中在MVC模式设计和实现上,所以UI方面几乎没有一点修饰。之所以在这里跟大家分享这个东西,是因为我自己通过读该老外的代码并仿照着写留言板对MVC的概念和具体实现有了些认识,希望了解MVC具体实现的朋友可以参考一下。
首先通俗地说说我对MVC的理解:Model是负责干活的,它干的活主要是从数据库中 获取需要的数据以及对获取的数据按照业务逻辑进行加工处理,至于为什么要干某件活,何时干某件活它一概不管,而这正是Controller的职 责,Controller像个餐馆招待,接到食客的需求,马上传达给厨房,Model就是大厨。View负责最终把菜端上桌,摆在合适的位置上。比如说客 人来了要了个糖醋鲤鱼,接待客人的是Controller,它会通知Model做一道糖醋鲤鱼,做好之后它又会招呼View把菜端上桌,View知道这是 主菜,它会把它摆在桌子中央。MVC的最大优势就在于把数据处理、流程控制和UI显示较好地分离开来,便于程序的开发和维护。
好了,下面看具体实现。
这个小程序一共包含6个文件,其中index.php是程序入口、post.htm是留言表单、在lib文件夹里Model、View 、Controller三个文件分别实现MVC,DataAccess是一个简单的数据库访问类。


<?php

/**

*  一个用来访问MySQL的类

*  仅仅实现演示所需的基本功能,没有容错等

*  代码未作修改,只是把注释翻译一下,加了点自己的体会

*/

class DataAccess {

var $link_id; //用于存储数据库连接

var $query_id; //用于存储查询源

//! 构造函数.

/**

* 创建一个新的DataAccess对象

* @param $host 数据库服务器名称

* @param $user 数据库服务器用户名

* @param $pass 密码

* @param $db   数据库名称

*/

function __construct($host,$user,$pass,$db) {

$this->link_id=mysql_pconnect($host,$user,$pass); //连接数据库服务器

mysql_select_db($db,$this->link_id);              //选择所需数据库

mysql_query("set names utf8;");

}

//! 执行SQL语句

/**

* 执行SQL语句,获取一个查询源并存储在数据成员$query中

* @param $sql  被执行的SQL语句字符串

* @return void

*/

function query($sql) {

$this->query_id=mysql_unbuffered_query($sql,$this->link_id); // Perform query here

if ($this->query_id) return true;

else return false;

}

//! 获取结果集

/**

* 以数组形式返回查询结果的所有记录

* @return mixed

*/

function fetchRows($sql) {

$this->query($sql);

$arr=array();

$i=0;

while( $row=mysql_fetch_array($this->query_id,MYSQL_ASSOC) )

//MYSQL_ASSOC参数决定了数组键名用字段名表示

{   $arr[$i]=$row;

$i++;

}

return $arr;

}

}

?>

复制代码

下面再来介绍一下Model类。
这个类也很简单,里面的函数一看就知道,是针对各种数据操作的,它通过DataAccess访问数据库。


<?php

//! Model类

/**

* 它的主要部分是对应于留言本各种数据操作的函数

* 如:留言数据的显示、插入、删除等

*/

class Model {

var $dao; //DataAccess类的一个实例(对象)

//! 构造函数

/**

* 构造一个新的Model对象

* @param $dao是一个DataAccess对象

* 该参数以地址传递(&$dao)的形式传给Model

* 并保存在Model的成员变量$this->dao中

* Model通过调用$this->dao的fetch方法执行所需的SQL语句

*/

function __construct(&$dao) {

$this->dao=$dao;

}

function listNote() {    //获取全部留言

$notes=$this->dao->fetchRows("SELECT * FROM note ORDER BY timedate DESC");

return $notes;

}

function postNote() {    //插入一条新留言

$name=$_POST['username'];

$email=$_POST['email'];

$content=$_POST['content'];

$timedate=time()+8*3600;

$sql="INSERT INTO note (name, email, content, timedate) VALUES

('".$name."', '".$email."', '".$content."', '".$timedate."' )";

//echo $sql;  //对于较复杂的合成SQL语句,<br />

//调试时用echo输出一下看看是否正确是一种常用的调试技巧

if ($this->dao->query($sql)) return true;

else return false;

}

function deleteNote() {   //删除一条留言,$id是该条留言的id

$sql="DELETE FROM note WHERE id=".$_GET['id'];

if ($this->dao->query($sql)) return true;

else return false;

}

}

?>

复制代码

看完这两个类之后你可能会发现这与以前我们写程序差不多,的确现在还闻不到MVC的味道,如果你不懂MVC,在这两个类的基础上你完全可以开始写你以前的程序了。例如要显示全部留言,只需要写入下代码:


<?php

require_once('lib/DataAccess.php');

require_once('lib/Model.php');

$dao=& new DataAccess ('localhost','root','password','test');

$model=& new Model($dao);

$notes=$model->listNote();

……

?>

复制代码

很亲切吧,呵呵。
有了这个“感情基础”你就不会对MVC望而生畏了,下面我们就要上今天的主菜了,那就是“Controller”闪亮登场!
先大体浏览一下主要结构,它包括一个Controller类以及派生出的三个子类(listController对应显示留言功能、postController对应发表留言功能以及deleteController对应删除留言功能)。


<?php

//! Controller

/**

* 控制器将$_GET['action']中不同的参数(list、post、delete)

* 对应于完成该功能控制的相应子类

*/

class Controller {

var $model;  // Model 对象

var $view;   // View  对象

//! 构造函数

/**

* 构造一个Model对象存储于成员变量$this->model;

*/

function __construct (& $dao) {

$this->model=& new Model($dao);

}

function getView() {    //获取View函数

//返回视图对象view

//对应特定功能的Controller子类生成对应的View子类的对象

//通过该函数返回给外部调用者

return $this->view;

}

}

//用于控制显示留言列表的子类

class listController extends Controller{   //extends表示继承

function __construct (& $dao) {

parent::__construct($dao);  //继承其父类的构造函数

//该行的含义可以简单理解为:

//将其父类的构造函数代码复制过来

$notes=$this->model->listNote();

$this->view=& new listView($notes);

//创建相应的View子类的对象来完成显示

}

}

//用于控制添加留言的子类

class postController extends Controller{

function __construct (& $dao) {

parent::__construct($dao);

if ($this->model->postNote()) $success=1;

else $success=0;

$this->view=& new postView($success);

}

}

//用于控制删除留言的子类

class deleteController extends Controller{

function __construct (& $dao) {

parent::__construct($dao);

if ($this->model->deleteNote()) $success=1;

else $success=0;

$this->view=& new deleteView($success);

}

}

?>

复制代码

大体浏览之后,你一定打算开始仔细研究它了吧,别急,为了心中有数,我们先从宏观着眼,先看看总入口index.php是如何调用Controller的:

<html>

<head>

<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />

<title>PHP MVC留言板</title>

</head>

<body leftmargin=”50px”>

<a href=”notebook.htm”>添加新留言</a><br>

<p>

<?php

//!index.php 总入口

/**

* index.php的调用形式为:

* 显示所有留言:index.php?action=list

* 添加留言    :index.php?action=post

* 删除留言    :index.php?action=delete&id=x

*/

require_once(‘lib/DataAccess.php’);

require_once(‘lib/Model.php’);

require_once(‘lib/View.php’);

require_once(‘lib/Controller.php’);

//创建DataAccess对象(请根据你的需要修改参数值)

$dao=& new DataAccess (‘localhost’,'root’,'your password here’,'notebook’);

//根据$_GET["action"]取值的不同调用不同的控制器子类

$action=$_GET["action"];

switch ($action)

{

case ”post”:

$controller=& new postController($dao); break;

case ”list”:

$controller=& new listController($dao); break;

case ”delete”:

$controller=& new deleteController($dao); break;

default:

$controller=& new listController($dao); break; //默认为显示留言

}

$view=$controller->getView(); //获取视图对象

$view->display();             //输出HTML

?>

</body>

</html>

复制代码

看过index.php之后你就更清楚了吧,原来功能是通过$_GET[“action”]指定的,由一个switch结构分发,不同的功能对应不同的Controller子类。现在可以滚上去(滚动页面上去的简称,绝非不洁用语^_^)仔细看看这个Controller代码了。注释应该很细了,不懂的地方就去看看PHP5的OOP语法和概念吧,单纯看这些概念总是越看催眠效果越好,现在带着实际问题去看,应该有所不同吧。不过我还是建议你在完成这个MVC的Hello World知道MVC是怎么回事之后下功夫打好OOP的基础,毕竟那是根本啊。
怎么样,Controller真是个光说不练的家伙吧,看不到三行它就把你引向View了,那就看看View吧。
View 里有对应的子类,负责相应功能的显示。理解了Controller,View的代码就不难看了,难看的话也是因为混杂着HTML的原因,它所做的就是把 Controller(Controller是个二道贩子,它的数据来自Model)给它的数据,然后塞到HTML中。


<?php

//! View 类

/**

* 针对各个功能(list、post、delete)的各种View子类

* 被Controller调用,完成不同功能的网页显示

*/

class View {

var $output; //用于保存输出HTML代码的字符串

function display() {  //输出最终格式化的HTML数据

echo($this->output);

}

}

class listView extends View   //显示所有留言的子类

{

function __construct($notes)

{

foreach ($notes as $value)

{

$this->output.="<p><strong>访客姓名:</strong>".$value['name']."</p>".

"<p><strong>访客邮箱:</strong>".$value['email']."</p>".

"<p><strong>访客留言:</strong>".$value['content']."</p>".

"<p><strong>来访时间:</strong>".date("y-m-d H:i",$value['timedate'])."</p>".

"<p align=\"right\"><a href=\"index.php?action=delete&id=".$value['id']."\">删除留言</a>".

"<hr />";

}

}

}

class postView extends View  //发表留言的子类

{

function __construct($success)

{

if ($success)

$this->output="留言成功!<br><a href=\"".$_SERVER['PHP_SELF']."?action=list\">查看</a>";

else

$this->output="留言保存失败!";

}

}

class deleteView extends View  //删除留言的子类

{

function __construct($success)

{

if ($success)

$this->output="留言删除成功!<br><a href=\"".$_SERVER['PHP_SELF']."?action=list\">查看</a>";

}

}

?>

复制代码

之所以UI方面写得如此简陋,是因为这些工作可以交给Smarty这样的模板去做,而我们这里就像集中精力研究MVC,不想把Smarty扯进来,所以就这样凑合了,以后我们可以再把Smarty结合进来。

看了这个东西之后不知你是否对MVC的概念和实现更明白了一点。
我也是个初学者,这是个依葫芦画瓢之作,目的就是想了解一下MVC,如果你是高手,我很想得到你的点评,这样的划分和架构是否符合MVC的理念?还有哪些应该改进之处?
当然,大家都知道现在很多关于MVC的争论,这很正常,就像关于开发语言的争论一样,永无休止,学术上的争论有助于创新。作为我们学技术、用技术而言,一 定要踏实深入学习,掌握了基本用法之后再去讨论,那才是更高层次的发展,在自己都搞不清的情况下在哪里争论只能是浪费时间。
下面说说我体会到的MVC的好处,它的确给程序的功能扩展带来方便,比如这个例子我们想要增加一个根据用户名查询留言的功能,只需要在Model里增加一 个查询函数(突然发现这些函数的用法很像存储过程),Controller和View里增加相应的子类,这种分离带来的好处是程序功能模块可以即插即用, 再就是整个程序的逻辑非常清晰。我想,对于需求变动频繁的Web应用来说,这种特性也许是很有价值的。

分类: 编程开发 标签:

IE6双倍边距 (双陪margin) 解决办法

2011年1月16日 没有评论

问题:在IE6下如果某个标签使用了float属性,同时设置了其外补丁“margin:10px 0 0 10px”可以看出,上边距和左边距同样为10px,但第一个对象距左边有20px。

解决办法:当将其display属性设置为inline时问题就都解决了。

说明:这是因为块级对象默认的display属性值是block,当设置了浮动的同时,还设置了它的外边距就会出现这种情况。也许你会问:“为 什么第二个对象和第一个对象之间就不存在双倍边距的BUG”?因为浮动都有其相对应的对象,只有相对于其父对象的浮动对象才会出现这样的问题。第一个对象 是相对父对象的,而第二个对象是相对第一个对象的,所以第二个对象在设置后不会出现问题。另外在一些特殊布局中,可能需要组合使用 display:block;和display:inline;才能达到预期效果。
当然最坏的情况下,我们就可以使用”margin:10px 0 0 10px;*margin:10px 0 0 10px;_margin:10px 0 0 5px”,这种“标准属性;*IE7识别属性;_IE6识别属性”HACK方式解决。

总结:这个现象仅当块级对象设置了浮动属性后才会出现,内联对象(行级对象)不会出现此问题。并且只有设置左边距和右边距的值才会出问题,上下边距不会出现问题。

分类: 编程开发 标签: