2008年10月16日
这是最终确定的 JavaScript 基于消息传递编程风格的文章“OOP 诡异教程(上)”的下篇。原文地址:http://let-in.blogspot.com/2007/06/oop.html。原来的想法是以风格开头,谈到 JavaScript 的内部机制,但作者 lichray 迟迟没有动键盘,认为不如利用已有的风格做一套机制出来,这样可能更有意义。于是,就有了这个更加“诡异”的下篇。

四. 扩展的实现
上文最后给出了一个“看上去很美”的基于消息传递的编程风格,比如构造一个 People 类的代码类似:

function People () {
  var money = 0
  function setMoney (dollars) {
    money = dollars
  }
  function pay (dollars) {
    money -= dollars
  }
  return (function (verb) {
    return eval(verb)
  })
}

有了这样的语法我们就可以描述不少句子了。但是存在一个问题:现实中的 Objects 之间是存在关系的——比如,forrest 是个 IQ 为 75 的傻子,傻子是 People 的一种。而我们仅仅是生搬硬套了一种语法而割裂了这种 "is-a" 关系。现在我们的工作,目的之一就是让这样一个“真切”的世界从我们已有的编程风格的地基上拔地而起。
到底应该怎样做才能使 Fool 产生的对象都能响应 People 的消息呢?我们要给 Fool 产生的对象(也就是返回的那个匿名函数啦)都添加这样一种能力:如果在 Fool 中响应不了消息,那就反馈给 People 响应。

function Fool (iq) {
  var IQ = iq || 0
  function init (iq) {
    IQ = iq
  }
  return (function (verb) {
    try {
      return eval(verb)
    } catch (e) {
      return People()(verb)
    }
  })
}

js> forrest = Fool()
js> forrest('init')(75)
js> forrest('IQ')
75
js> forrest('money')
0

五. 语法扩展和代码生成
这下代码量增加了很多,强迫潜在的使用者们在创建每个类时都这样写那实在是令人抓狂。本来这篇文章应该不提此类问题的解决,但考虑到有益于读者理解“机制”这个抽象概念,这里给出一个可行的方案——把普通的类代码用 Function() 函数重编译为可用的 JavaScript 函数。也就是说,我们能给出类扩展的代码并指定被扩展的类来获取类似上文的代码:

Fool = extend('People()', function (iq){
  var IQ = iq || 0
  function init (iq) {
    IQ = iq
  }
})

为了方便字符串操作,我们希望编译后的代码的参数部分(如 People())都集中出现在一个位置且尽可能便于定位。在函数头添加一句

var origin = People()

当然是可行的,这样还能使 Fool 内部显式引用到其超类。但这样还不够漂亮。我们修改编译后的样例代码为:

function () {
  return (function (origin) {
    var IQ = 0
    function init (iq) {
      IQ = iq
    }
    return (function (verb) {
      try {
        return eval(verb)
      } catch (e) {
        return origin(verb)
      }
    })
  })(People())
}

这个利用参数传递变量的小技巧不值得学习,实际效率不高。但在这篇文章中,这样绑定特殊变量的技术是标准方案。
那么,extend() 函数的实现为:

function extend (originc, code) {
  function argsArea (code) {
    // 题外话,正则表达式也有不值得使用的时候
    return code.slice(code.indexOf('(')+1, code.indexOf(')'))
  }
  function bodyCode (code) {
    // 不用 trim() 了,没事儿找事儿
    return code.slice(code.indexOf('{')+1, code.lastIndexOf('}'))
  }
  function format (body) {
    var objc = bodyCode(function () {
      return (function (verb) {
        try {
          return eval(verb)
        } catch (e) {
        return origin(verb)
        }
      })
    }.toString())
    return 'return (function (origin) {'+body+objc+'})('+originc+')'
  }
  var $ = code.toString()
  return Function(argsArea($), format(bodyCode($)))
}

这样前文提到过的 extend 的实例代码就可以正常运行了,测试代码不再重复。

六. 机制完备化
这样,我们的基于消息传递编程风格的一套面向对象机制就确定下来了。机制是宪法,是语言的根本大法,有了它,我们就可以通过修改代码生成器,很快地给这套机制进行完备化。
想法有很多,例子只举两个。
第一个例子:类的定义中应该能直接引用到将产生的对象 self。答案只有一句话:把返回的那个作为对象的匿名函数命名为 self。
第二个例子:既然是单继承模式,应当存在一个顶层类 AbsObj,使没有指定继承的类自动继承它。答案也只有一句话:在 extend 函数体第一行添加代码:

if (arguments.length == 1) {
  code = originc
  originc = 'AbsObj()'
}

然后手工构造设计 AbsObj 类,为空也无所谓。不过当然了,一般都会给顶层类添加一些全局性质的消息绑定。由于是“底层操作”,基本上都需要修改 extend 函数。做了一个简单的:

function AbsObj () {
  //检测是否能响应此 verb,要再用一次异常处理
  function canHandle(verb){
    try {
      // 别担心这里的 self 会传递不过去
      self(verb)
    } catch (e) {
      return false
    }
    return true
  }
  function toString() {} // 这个搞起来其实很麻烦~`
  var self = function (verb) {
    return eval(verb)
  }
  return self
}

js> Obj=extend(function(){x=5})
js> o=Obj()
js> o('canHandle')('x')
true
js> o('canHandle')('y')
false

文章写完了,小结一下。消息传递的编程不仅仅是一种代码风格,还可以成长为一种完备的机制。这种完备性远不只是这两篇加起来不到300行的文章所能覆盖的(例如非常彻底的“万物皆对象”,因为只要是能响应消息的函数,连接一下 AbsObj 就是合法对象了;类,函数都可以),大家可以试着玩一玩,顺便体会一下这个计算模型的透明和强大。
另外,熟悉函数式编程的朋友可以帮忙思考一下:这样一个基于闭包变换的计算模型实质上是函数式的,再配合动态的函数式的对象级继承(用一个匿名类代换一下)就能在纯 FP 真正下实现 OOP 了。可惜的是每一次更新操作都要重新生成对象,性能代价大了点,不知道大家有什么好想法。
posted @ 2008-10-16 09:45 咖啡猪 阅读(21) | 评论 (0)编辑
  2008年9月23日

串口调试程序v1.0(模拟sscom设计)

 

C#2.0开发。

开发:apple
时间:2006
公司:陵嘉防伪技术(上海)有限公司
联系:icelenix@163.com

程序界面:

 程序下载:

http://files.cnblogs.com/4kapple/LJ_myMScomm.rar

 

posted @ 2008-09-23 14:47 咖啡猪 阅读(377) | 评论 (2)编辑
  2008年9月22日
     摘要: 最近也在接触SOCKET编程,在当今这样一个网络时代,很多技术都以网络为中心在诞生,至少我认为是这样的,而SOCKET套接字接口,在实现网络通讯上处于关键地位,所以不会SOCKET是不行的。首先,本文主要是针对那些刚接触SOCKET编程的朋友,如果是高手,就可以不看此文啦,可以去陪陪老婆,比如逛街或看电视...在开始之前,我们需要预习一些基础知识:什么是SOCKET套接字?SOCKET通常有那几种... 阅读全文
posted @ 2008-09-22 12:26 咖啡猪 阅读(104) | 评论 (0)编辑
  2008年9月17日

微软Zune 3.0正式发布 新机图赏

投递人 itnews 发布于 2008-09-17 12:17 评论(2) 有66人阅读 [收藏]

微软今天正式发布了第三代Zune媒体播放器,升级主要体现在软件方面,旧款机型也可以免费升级到3.0版软件。

Zune 3.0的主要升级内容我们上周已经进行过介绍,这里不再赘述。虽然新机从硬件上乏善可陈,但微软的强项在这里一览无余。Zune 3.0版PC端软件界面相当华丽,相信会博得许多用户的欢心。

Zune 3.0升级下载页面:
http://www.zune.net/en-us/products/zunesoftware/download.htm

本地下载:
http://drivers.mydrivers.com/drivers/234-93810-Microsoft-Zune-3.0-For-WinXP-WinXP-64-XPMCE-Vista-Vista-64/

微软Zune 3.0正式发布 新机图赏

PC端软件界面

微软Zune 3.0正式发布 新机图赏

微软Zune 3.0正式发布 新机图赏

微软Zune 3.0正式发布 新机图赏

微软Zune 3.0正式发布 新机图赏

微软Zune 3.0正式发布 新机图赏

微软Zune 3.0正式发布 新机图赏

新款120GB硬盘机型

微软Zune 3.0正式发布 新机图赏

微软Zune 3.0正式发布 新机图赏

微软Zune 3.0正式发布 新机图赏

微软Zune 3.0正式发布 新机图赏

微软Zune 3.0正式发布 新机图赏

新款16GB闪存机型

微软Zune 3.0正式发布 新机图赏

微软Zune 3.0正式发布 新机图赏

微软Zune 3.0正式发布 新机图赏

微软Zune 3.0正式发布 新机图赏

微软Zune 3.0正式发布 新机图赏

微软Zune 3.0正式发布 新机图赏

新16GB款拆包

微软Zune 3.0正式发布 新机图赏

微软Zune 3.0正式发布 新机图赏

微软Zune 3.0正式发布 新机图赏

微软Zune 3.0正式发布 新机图赏

微软Zune 3.0正式发布 新机图赏

微软Zune 3.0正式发布 新机图赏

微软Zune 3.0正式发布 新机图赏

微软Zune 3.0正式发布 新机图赏

微软Zune 3.0正式发布 新机图赏


 

 

 

 
来自: 驱动之家
posted @ 2008-09-17 13:09 咖啡猪 阅读(35) | 评论 (0)编辑

今天(确切的说,昨天晚上),我们的技术团队对所有服务器进行正常的停机维护,先在社区里面发了公告贴,然后大约在18点左右,在整站的顶部进行了通告,说“大众点评网将于2008年9月11日 23:00 至 2008年9月12日 8:00 进行系统维护,届时网站可能不能正常访问,敬请谅解!”。

趁着23点没到,我还特地做了一个停机维护页面,上面调侃的写了一句话“大众点评网的服务器长期不堪重负,终于累趴下了。放心!工程师正在人工呼吸,开着小绵羊给我们送只强心针来吧!!”,然后在下面放了一个小绵羊赛车的游戏。算是有点创意吧??

[04:59更新]开机了,停机维护页面原封不动放上来给大家看看,点击

忙忙碌碌、紧紧张张的工作到4点左右,打开搜索引擎,出现几条很让人哭笑不得的新闻。在腾讯网的科技频道,互联网新闻里面,突然出现“大众点评今日突然无法打开 停机维护暂无期限”。而且还很白目的写道“目前尚无法确认该网站是何时开始停机维护,大众点评也未公布停机维护的时长,以及恢复的时间。”。很快,和讯就转载了这个新闻。

亲爱的编辑同志,我们在页面顶端很清楚的写明了停机的开始时间截至时间,怎么就变成无法确认了呢。

在这里劝站长们,不要轻易停机维护,就算要停机维护也不能出公告~~~会很冤枉的~~~我这就开机去~~~

posted @ 2008-09-17 11:18 咖啡猪 阅读(45) | 评论 (0)编辑
Javascript libraries roundup  

Prototype
Prototype is a JavaScript framework that aims to ease development of dynamic web applications.

Homepage: http://prototype.conio.net

Documentation:
http://blogs.ebusiness-apps.com/jordan/pages/Prototype%20Library%20Info.htm
http://www.sergiopereira.com/articles/prototype.js.html
http://wiki.script.aculo.us/scriptaculous/show/Prototype

Rico
Rico provides a very simple interface for registering Ajax request handlers as well as HTML elements or JavaScript objects as Ajax response objects. Multiple elements and/or objects may be updated as the result of one Ajax request.

Homepage: http://openrico.org/rico/home.page
Documentation: http://openrico.org/rico/docs.page
Demos: http://openrico.org/rico/demos.page

MochiKit
MochiKit is a highly documented and well tested, suite of JavaScript libraries that will help you get things done, fast.

Homepage: http://www.mochikit.com/
Documentation: http://www.mochikit.com/doc/html/MochiKit/index.html
Demos: http://www.mochikit.com/demos.html

Dojo Toolkit
Dojo is an Open Source toolkit that allows you to easily build dynamic capabilities into web pages and any other environment that supports JavaScript. Dojo provides components that let you make your sites more useable, responsive, and functional.

Homepage: http://www.dojotoolkit.org/
Documentation: http://dojotoolkit.org/docs/
Demos: http://dojotoolkit.org/examples/

Behaviour
Separate Structure (xhtml) from Behavior (javascript)

Homepage: http://bennolan.com/behaviour/

Solvent
The Solvent is a cross-browser AJAX application toolkit written in JavaScript. The Solvent is provided as modules or as an entire toolkit. The projects focus is to promote robust web applications and enable rapid web development.

Homepage: http://sourceforge.net/projects/solvent/
Documentation: http://sourceforge.net/docman/?group_id=144164

Moo.FX
moo.fx is a superlightweight, ultratiny, megasmall javascript effects library, written with prototype.js.

Homepage: http://moofx.mad4milk.net/
Demo: http://moofx.mad4milk.net/tests.html

WZ_DradDrop
A Cross-browser JavaScript DHTML Library which adds Drag Drop functionality to layers and to any desired image

Homepage: http://www.walterzorn.com/dragdrop/dragdrop_e.htm

WZ_jsGraphics
High Performance JavaScript Vector Graphics Library.

Homepage: http://www.walterzorn.com/jsgraphics/jsgraphics_e.htm

overLIB
overLIB is a JavaScript library created to enhance websites with small popup information boxes (like tooltips) to help visitors around your website.

Homepage: http://www.bosrup.com/web/overlib/
Documentation: http://www.bosrup.com/web/overlib/?Documentation
Command reference: http://www.bosrup.com/web/overlib/?Command_Reference

Scriptaculous
Javascript visual effects, togather with prototype.js

Homepage: http://script.aculo.us/

SACK
Simple AJAX Code-Kit

Homepage: http://twilightuniverse.com/projects/sack/
Documentation: http://twilightuniverse.com/projects/sack/docs.php

Sarissa
Sarissa is an ECMAScript library acting as a cross-browser wrapper for native XML APIs. It offers various XML related goodies like Document instantiation, XML loading from URLs or strings, XSLT transformations, XPath queries etc and comes especially handy for people doing what is lately known as “AJAX” development.

Homepage: http://sarissa.sourceforge.net/doc/

Nifty Corners
A small library for making rounded corners with Javascript.

Homepage: http://pro.html.it/esempio/nifty/nifty1js.html

dp.SyntaxHighlighter
dp.SyntaxHighlighter is a free JavaScript library for source code syntax highlighting.

Homepage: http://www.dreamprojections.com/SyntaxHighlighter/
Documentation: http://www.dreamprojections.com/SyntaxHighlighter/Usage.aspx
Demo: http://www.dreamprojections.com/SyntaxHighlighter/Examples.aspx

AJAX.NET
Michael Schwarz, a .NET developer in Germany has released the latest version of his Ajax .NET Wrapper. This class library simplifies the use of XMLHttp by providing .NET objects that generate the necessary Javascript code.

Homepage: http://weblogs.asp.net/mschwarz/archive/2005/04/07/397504.aspx

TOXIC
Toxic is an AJAX toolkit, or framework, for creating rich web applications. It handles the tedious and repetetive tasks involved in integrating a client created using html and javascript with a server backend. It enables client side javascript to directly call class methods in PHP5 (or any other suitable language). It also enables the server side PHP to directly call client side javascript functions. Using Toxic you can get rid of much of the tedious work in form intensive rich web applications.

Homepage: http://www.dotvoid.com/view.php?id=40

Plex Toolkit
Open source feature-complete DHTML GUI toolkit and AJAX framework based on a Javascript/DOM implementation of Macromedia’s Flex technology. Uses the almost identical markup language to Flex embedded in ordinary HTML documents for describing the UI. Binding is done with Javascript.

Homepage: http://www.plextk.org/

CPaint
CPAINT (Cross-Platform Asynchronous INterface Toolkit) is a multi-language toolkit that helps web developers design and implement AJAX web applications with ease and flexibility.

Homepage: http://cpaint.booleansystems.com/
Docs: http://cpaint.booleansystems.com/doc/

DOM-Drag
DOM-Drag is a lightweight, easy to use, dragging API for modern DHTML browsers.

Homepage: http://www.youngpup.net/2001/domdrag/
Tutorials: http://www.youngpup.net/2001/domdrag/tutorial
Demo: http://www.youngpup.net/2001/domdrag/examples

Tibet
Enterprise Class AJAX

Homepage: http://www.technicalpursuit.com/ajax.htm

Zimbra
Rubust AJAX framework

Homepage: http://www.zimbra.com
Documentation: http://www.zimbra.com/products/documentation.html
Demo: http://www.zimbra.com/products/hosted_demo.php

qooxdoo
qooxdoo is an advanced open-source javascript based toolkit. qooxdoo continues where simple HTML is not enough anymore. This way qooxdoo can help you to get your rich web application interface done - easier than ever before.

Homepage: http://qooxdoo.oss.schlund.de
Documentation: http://qooxdoo.oss.schlund.de/section/documentation
Demo: http://qooxdoo.oss.schlund.de/counter/refer.php?id=5

AJFORM
AJFORM is a JavaScript toolkit which simply submits data from any given form in an HTML page, then sends the data to any specified JavaScript function. AJFORM degrades gracefully in every aspect. In other words, if the browser doesn’t support it, the data will be sent through the form as normal.

Homepage: http://redredmusic.com/brendon/ajform/

ThyApi
ThyAPI is an api to allow the developement of better user interfaces for web applicaticions, Using javascript and Ajax, it allows a complete visual interface definition using CSS and encapsulates all objects data manipulateion.

Homepage: http://sourceforge.net/projects/thyapi/

Engine
Engine for Web Applications is an application framework for client-side development and Web applications. It provides an environment in which to develop and run JavaScript components and applications.

Homepage: http://www.imnmotion.com/projects/engine/
Documentation: http://www.imnmotion.com/projects/engine/api/engine_api.html

AJAXGear Toolkit
It is a toolkit that allows you to take advantage of the client-side technique known as AJAX. AJAX is shorthand for Asynchronous JavaScript and XML. It uses the XMLHttpRequest object to allow a Web browser to make asynchronous call to the Web server without the need to refresh the whole page.

Homepage: http://www.ajaxgear.com

Interactive Website Framework
A framework for creating highly interactive websites using javascript, css, xml, and html. Includes a custom xml parser for highly readable javascript. Essentially, all the plumbing for making AJAX-based websites, with js-based GUI toolkit.

Homepage: http://sourceforge.net/projects/iwf/

RSLite
RSlite is an extremely lightweight implementation of remote scripting which uses cookies. It is very widely browser-compatible (Opera!) but limited to single calls and small amounts of data.

Homepage: http://www.ashleyit.com/rs/main.htm
Demo: http://www.ashleyit.com/rs/techniques.htm

XHConn
XMLHTTP is a technology with which a developer can access external resources over HTTP from a static web page without ever having to reload the page itself. This library is meant to simplify and unify the code necessary to successfully send and receive simple data via XMLHTTP.

Homepage: http://xkr.us/code/javascript/XHConn/

Taconite
Taconite is a framework that simplifies the creation of Ajax enabled Web applications. It’s a very lightweight framework that automates the tedious tasks related to Ajax development, such as the creation and management of the XMLHttpRequest object and the creation of dynamic content.

Homepage: http://taconite.sourceforge.net/
Documentation: http://taconite.sourceforge.net/docs/jsdocs/index.html
Demo: http://taconite.sourceforge.net/examples.html

qForms
Great Javascript API for interfacing forms.

Homepage: http://pengoworks.com/index.cfm?action=get:qforms
Documentation: http://pengoworks.com/qforms/docs/
Demo: http://pengoworks.com/qforms/docs/examples/

JSPkg
jspkg is a package loader for Javascript, based on pluggable loaders for locating and loading scripts into a client-side Javascript application. It is designed to work best with unobtrusive Javascript libraries, but doesn’t impose any methodology or design on its users.

Homepage: http://jspkg.sourceforge.net/

Ajaxcaller
AjaxCaller is a thin XMLHttpRequest wrapper used in all the AjaxPatterns demos. The focus is on ease-of-use and full HTTP method support.

Homepage: http://ajaxify.com/run/testAjaxCaller/

libXmlRequest
The XmlRequest library contains a two public request functions, getXml and postXml, that may be used to send synchronous and asynchronous XML Http requests from Internet Explorer and Mozilla.

Homepage: http://www.whitefrost.com/reference/2005/09/09/libXmlRequest.html

SAJAX
Sajax is an open source tool to make programming websites using the Ajax framework 鈥?also known as XMLHTTPRequest or remote scripting 鈥?as easy as possible. Capable of stubbing calls to numerous server-side platforms: ASP/ ColdFusion/ Io/ Lua/ Perl/ PHP/ Python/ Ruby

Homepage: http://www.modernmethod.com/sajax/
Demo: http://www.modernmethod.com/sajax/examples.phtml

Sardalya
A small library for making dynamic HTML programming easy and fun.

Homepage: http://www.sarmal.com/sardalya/Default.aspx
Demo: http://www.sarmal.com/sardalya/Samples.aspx

X
One of the best javascript libraries out there.

Homepage: http://www.cross-browser.com/toys/

AjaxRequest
AjaxRequest is a layer over the XMLHttpRequest functionality which makes the communication between Javascript and the server easier for developers.

Homepage: http://ajaxtoolbox.com/request/
Documentation: http://ajaxtoolbox.com/request/documentation.php
Demo: http://ajaxtoolbox.com/request/examples.php

PHP based AJAX Frameworks

AjaxAC
AjaxAC is an open-source framework written in PHP, used to develop/create/generate AJAX applications. The fundamental idea behind AJAX (Asynchronous JavaScript And XML) is to use the XMLHttpRequest object to change a web page state using background HTTP sub-requests without reloading the entire page.

Homepage: http://ajax.zervaas.com.au

XOAD
XOAD, formerly known as NAJAX, is a PHP based AJAX/XAP object oriented framework that allows you to create richer web applications.

Homepage: http://www.xoad.org
Documentation: http://www.xoad.org/documentation/source/
Demo: http://www.xoad.org/examples/

PAJAJ
What is the PAJAJ framework, it stands for (PHP Asynchronous Javascript and JSON). It is a object oriented Ajax framework written in PHP5 for development of event driven PHP web applications.

Homepage: http://sourceforge.net/projects/pajaj/
Documentation: http://www.wassons.org/pajaj/public/docs/index.php

Symfony
A PHP 5 Development Framework inspired by Rails. It has integrated database abstraction and support for AJAX. Installation is fairly easy. Symfony is aimed at building robust applications in an enterprise context. This means that you have full control over the configuration: from the directory structure to the foreign libraries, almost everything can be customized. To match your enterprise’s development guidelines, symfony is bundled with additional tools helping you to test, debug and document your project.

AjaxBlog: http://ajaxblog.com/arc…….application-in-php-in-minutes-with-symfony

Homepage: www.symfony-project.com
Documentation: http://www.symfony-project.com/content/documentation.html
http://www.symfony-project.com/trac/wiki

XAJAX
xajax is an open source PHP class library that allows you to easily create powerful, web-based, Ajax applications using HTML, CSS, JavaScript, and PHP. Applications developed with xajax can asynchronously call server-side PHP functions and update content without reloading the page.

Homepage: http://xajax.sourceforge.net/

PEAR:: HTML_AJAX
Provides PHP and JavaScript libraries for performing AJAX (Communication from JavaScript to your server without reloading the page)

Homepage: http://pear.php.net/package/HTML_AJAX
Documentation: http://pear.php.net/package/HTML_AJAX/docs

Flexible AJAX
Flexible Ajax is a handler to combine the remote scripting technology, also known as AJAX (Asynchronous Javascript and XML), with a php-based backend.

Homepage: http://tripdown.de/flxajax/
Demo: http://tripdown.de/flexible_ajax_example.php

Javascript libs for Flash:

FlashObject
FlashObject is a small Javascript file used for embedding Macromedia Flash content.

Homepage: http://blog.deconcept.com/flashobject/

OSFlash - Flashjs
The Flash JavaScript Integration Kit allows developers to get the best of the Flash and HTML worlds by enabling JavaScript to invoke ActionScript functions, and vice versa.

Homepage: http://www.osflash.org/doku.php?id=flashjs
Documentation: http://www.mustardlab.com/developer/flash/jscommunication/

AFLAX
A JavaScript Library for Macromedia’s Flash鈩?Platform. AFLAX is a method through which developers may use JavaScript and Flash together to create AJAX-type applications, but with a much richer set of vector drawing controls than are available in either Internet Explorer or FireFox. Developers using this library have access to the full range of Flash features, but without ever touching the Flash IDE.

Homepage: http://www.aflax.org

Java based AJAX Frameworks

ZK
ZK is an AJAX-based solution for developing Web applications in Java. ZK includes an event-driven engine to automate interactivity, and a rich set of XUL-based components.

Homepage: http://zk1.sourceforge.net
Demo: http://www.potix.com/zkdemo/userguide

posted @ 2008-09-17 10:52 咖啡猪 阅读(78) | 评论 (0)编辑
  2008年8月19日
WMI(Windows Management Instrumentation)是Windows下可以与系统信息(包括软硬件等)的一个管理框架,通过WMI可以很方便地对机器进行管理。现在以通过WMI来打开(或创建)一个记事本(notepad.exe)进程为例,看看VC++到.Net的变迁,一览.Net是如何让程序员从繁琐晦涩的程序中解放出来。

1、预工作:
VC++中需要在源代码中加入:
#include <Wbemidl.h>
#pragma comment(lib, "wbemuuid.lib")

VC#中需要:
在工程中添加引用:System.Management
在代码中加入using System.Management;

2、流程:
VC++的代码,需要6步和查询返回值、最后释放资源:
// Step 1: --------------------------------------------------
// Initialize COM. ------------------------------------------
hres =  CoInitializeEx(0, COINIT_MULTITHREADED); 

// Step 2: --------------------------------------------------
// Set general COM security levels --------------------------
hres =  CoInitializeSecurity(
        NULL, 
        
-1,                          // COM negotiates service
        NULL,                        // Authentication services
        NULL,                        // Reserved
        RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication 
        RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation  
        NULL,                        // Authentication info
        EOAC_NONE,                   // Additional capabilities 
        NULL                         // Reserved
        );

// Step 3: ---------------------------------------------------
// Obtain the initial locator to WMI -------------------------
IWbemLocator *pLoc = NULL;
hres 
= CoCreateInstance(
        CLSID_WbemLocator,             
        
0
        CLSCTX_INPROC_SERVER, 
        IID_IWbemLocator, (LPVOID 
*&pLoc);

// Step 4: ---------------------------------------------------
// Connect to WMI through the IWbemLocator::ConnectServer method
IWbemServices *pSvc = NULL;
// Connect to the local root\cimv2 namespace
// and obtain pointer pSvc to make IWbemServices calls.
hres = pLoc->ConnectServer(
        _bstr_t(L
"ROOT\\CIMV2"), 
        NULL,
        NULL, 
        
0
        NULL, 
        
0
        
0
        
&pSvc
    );

// Step 5: --------------------------------------------------
// Set security levels for the proxy ------------------------
hres = CoSetProxyBlanket(
        pSvc,                        
// Indicates the proxy to set
        RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx 
        RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx 
        NULL,                        // Server principal name 
        RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx 
        RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
        NULL,                        // client identity
        EOAC_NONE                    // proxy capabilities 
    );

// Step 6: --------------------------------------------------
// Use the IWbemServices pointer to make requests of WMI ----
// set up to call the Win32_Process::Create method
BSTR MethodName = SysAllocString(L"Create");
BSTR ClassName 
= SysAllocString(L"Win32_Process");

IWbemClassObject
* pClass = NULL;
hres 
= pSvc->GetObject(ClassName, 0, NULL, &pClass, NULL);

IWbemClassObject
* pInParamsDefinition = NULL;
hres 
= pClass->GetMethod(MethodName, 0
        
&pInParamsDefinition, NULL);

IWbemClassObject
* pClassInstance = NULL;
hres 
= pInParamsDefinition->SpawnInstance(0&pClassInstance);

// Create the values for the in parameters
VARIANT varCommand;
varCommand.vt 
= VT_BSTR;
varCommand.bstrVal 
= L"notepad.exe";
// Store the value for the in parameters
hres = pClassInstance->Put(L"CommandLine"0,
        
&varCommand, 0);
wprintf(L
"The command is: %s\n", V_BSTR(&varCommand));

// Execute Method
IWbemClassObject* pOutParams = NULL;
hres 
= pSvc->ExecMethod(ClassName, MethodName, 0, NULL, pClassInstance, &pOutParams, NULL);

// Get return value
VARIANT varReturnValue;
hres 
= pOutParams->Get(_bstr_t(L"ReturnValue"), 0&varReturnValue, NULL, 0);

// Last: clean up
VariantClear(&varCommand);
VariantClear(
&varReturnValue);
SysFreeString(ClassName);
SysFreeString(MethodName);
pClass
->Release();
pInParamsDefinition
->Release();
pOutParams
->Release();
pLoc
->Release();
pSvc
->Release();
CoUninitialize();

VC#只需寥寥数行就可以实现(暂不考虑错误处理):
跳过VC++中的Step1~5,直接从Step6开始。而且非常直观:
ManagementClass mc = new  ManagementClass("Win32_Process");
ManagementBaseObject obj 
= mc.GetMethodParameters("Create");
obj[
"CommandLine"]="notepad.exe";
mc.InvokeMethod(
"Create", obj, null);
mc.Dispose();

.Net对WMI良好的封装,还有对字符串的更强支持、方便的垃圾回收机制,使程序既一目了然,又易于维护。其实类似的区别在VC vs VB年代已经出现了(特别是在COM组件编写和调用方面可以看出),从这点也可以看出.Net完全继承了VB易学易用的特性,又不失强大的功能。
posted @ 2008-08-19 16:17 咖啡猪 阅读(56) | 评论 (0)编辑
  2008年7月10日
在工业生产控制系统中,有许多需要定时完成的操作,如定时显示当前时间,定时刷新屏幕上的进度条,上位

机定时向下位机发送命令和传送数据等。特别是在对控制性能要求较高的实时控制系统和数据采集系统中,就更需要精确定时操作。
众所周知,Windows 是基于消息机制的系统,任何事件的执行都是通过发送和接收消息来完成的。 这样就带来了一些问题,如一旦计算机的CPU被某个进程占用,或系统资源紧张时,发送到消息队列 中的消息就暂时被挂起,得不到实时处理。因此,不能简单地通过Windows消息引发一个对定时要求 严格的事件。另外,由于在Windows中已经封装了计算机底层硬件的访问,所以,要想通过直接利用 访问硬件来完成精确定时,也比较困难。所以在实际应用时,应针对具体定时精度的要求,采取相适 应的定时方法。
VC中提供了很多关于时间操作的函数,利用它们控制程序能够精确地完成定时和计时操作。本文详细介绍了 VC中基于Windows的精确定时的七种方式,如下图所示:


图一 图像描述

方式一:VC中的WM_TIMER消息映射能进行简单的时间控制。首先调用函数SetTimer()设置定时 间隔,如SetTimer(0,200,NULL)即为设置200ms的时间间隔。然后在应用程序中增加定时响应函数 OnTimer(),并在该函数中添加响应的处理语句,用来完成到达定时时间的操作。这种定时方法非常 简单,可以实现一定的定时功能,但其定时功能如同Sleep()函数的延时功能一样,精度非常低,最小 计时精度仅为30ms,CPU占用低,且定时器消息在多任务操作系统中的优先级很低,不能得到及时响 应,往往不能满足实时控制环境下的应用。只可以用来实现诸如位图的动态显示等对定时精度要求不高的情况。如示例工程中的Timer1。
方式二:VC中使用sleep()函数实现延时,它的单位是ms,如延时2秒,用sleep(2000)。精度非常 低,最小计时精度仅为30ms,用sleep函数的不利处在于延时期间不能处理其他的消息,如果时间太 长,就好象死机一样,CPU占用率非常高,只能用于要求不高的延时程序中。如示例工程中的Timer2。
方式三:利用COleDateTime类和COleDateTimeSpan类结合WINDOWS的消息处理过程来实现秒级延时。如示例工程中的Timer3和Timer3_1。以下是实现2秒的延时代码:

COleDateTime      start_time = COleDateTime::GetCurrentTime();
COleDateTimeSpan end_time= COleDateTime::GetCurrentTime()-start_time;
while(end_time.GetTotalSeconds()< 2) //实现延时2秒
{
MSG msg;
GetMessage(&msg,NULL,0,0);
TranslateMessage(&msg);
DispatchMessage(&msg);

//以上四行是实现在延时或定时期间能处理其他的消息,
       //虽然这样可以降低CPU的占有率,
//但降低了延时或定时精度,实际应用中可以去掉。
end_time = COleDateTime::GetCurrentTime()-start_time;
}//这样在延时的时候我们也能够处理其他的消息。
方式四:在精度要求较高的情况下,VC中可以利用GetTickCount()函数,该函数的返回值是
DWORD型,表示以ms为单位的计算机启动后经历的时间间隔。精度比WM_TIMER消息映射高,在较 短的定时中其计时误差为15ms,在较长的定时中其计时误差较低,如果定时时间太长,就好象死机一样,CPU占用率非常高,只能用于要求不高的延时程序中。如示例工程中的Timer4和Timer4_1。下列代码可以实现50ms的精确定时:
DWORD dwStart = GetTickCount();
DWORD dwEnd = dwStart;
do
{
dwEnd = GetTickCount()-dwStart;
}while(dwEnd <50);
为使GetTickCount()函数在延时或定时期间能处理其他的消息,可以把代码改为:
DWORD dwStart = GetTickCount();
DWORD dwEnd = dwStart;
do
{
MSG msg;
GetMessage(&msg,NULL,0,0);
TranslateMessage(&msg);
DispatchMessage(&msg);
dwEnd = GetTickCount()-dwStart;
}while(dwEnd <50);
虽然这样可以降低CPU的占有率,并在延时或定时期间也能处理其他的消息,但降低了延时或定时精度。
方式五:与GetTickCount()函数类似的多媒体定时器函数DWORD timeGetTime(void),该函数定时精 度为ms级,返回从Windows启动开始经过的毫秒数。微软公司在其多媒体Windows中提供了精确定时器的底 层API持,利用多媒体定时器可以很精确地读出系统的当前时间,并且能在非常精确的时间间隔内完成一 个事件、函数或过程的调用。不同之处在于调用DWORD timeGetTime(void) 函数之前必须将 Winmm.lib 和 Mmsystem.h 添加到工程中,否则在编译时提示DWORD timeGetTime(void)函数未定义。由于使用该 函数是通过查询的方式进行定时控制的,所以,应该建立定时循环来进行定时事件的控制。如示例工程中的Timer5和Timer5_1。
方式六:使用多媒体定时器timeSetEvent()函数,该函数定时精度为ms级。利用该函数可以实现周期性的函数调用。如示例工程中的 Timer6和Timer6_1。函数的原型如下:
MMRESULT timeSetEvent( UINT uDelay, 
UINT uResolution,
LPTIMECALLBACK lpTimeProc,
WORD dwUser,
UINT fuEvent )
该函数设置一个定时回调事件,此事件可以是一个一次性事件或周期性事件。事件一旦被激活,便调用指定的回调函数, 成功后返回事件的标识符代码,否则返回NULL。函数的参数说明如下:
uDelay:以毫秒指定事件的周期。
Uresolution:以毫秒指定延时的精度,数值越小定时器事件分辨率越高。缺省值为1ms。
LpTimeProc:指向一个回调函数。
DwUser:存放用户提供的回调数据。
FuEvent:指定定时器事件类型:
TIME_ONESHOT:uDelay毫秒后只产生一次事件
TIME_PERIODIC :每隔uDelay毫秒周期性地产生事件。
具体应用时,可以通过调用timeSetEvent()函数,将需要周期性执行的任务定义在LpTimeProc回调函数 中(如:定时采样、控制等),从而完成所需处理的事件。需要注意的是,任务处理的时间不能大于周期间隔时间。另外,在定时器使用完毕后, 应及时调用timeKillEvent()将之释放。
方式七:对于精确度要求更高的定时操作,则应该使用QueryPerformanceFrequency()和 QueryPerformanceCounter()函数。这两个函数是VC提供的仅供Windows 95及其后续版本使用的精确时间函数,并要求计算机从硬件上支持精确定时器。如示例工程中的Timer7、Timer7_1、Timer7_2、 Timer7_3。
QueryPerformanceFrequency()函数和QueryPerformanceCounter()函数的原型如下:
BOOL  QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency);
BOOL QueryPerformanceCounter(LARGE_INTEGER *lpCount);
数据类型ARGE_INTEGER既可以是一个8字节长的整型数,也可以是两个4字节长的整型数的联合结构, 其具体用法根据编译器是否支持64位而定。该类型的定义如下:
typedef union _LARGE_INTEGER
{
struct
{
DWORD LowPart ;// 4字节整型数
LONG HighPart;// 4字节整型数
};
LONGLONG QuadPart ;// 8字节整型数

}LARGE_INTEGER ;
在进行定时之前,先调用QueryPerformanceFrequency()函数获得机器内部定时器的时钟频率, 然后在需要严格定时的事件发生之前和发生之后分别调用QueryPerformanceCounter()函数,利用两次获得的计数之差及时钟频率,计算出事件经 历的精确时间。下列代码实现1ms的精确定时:
LARGE_INTEGER litmp; 
LONGLONG QPart1,QPart2;
double dfMinus, dfFreq, dfTim;
QueryPerformanceFrequency(&litmp);
dfFreq = (double)litmp.QuadPart;// 获得计数器的时钟频率
QueryPerformanceCounter(&litmp);
QPart1 = litmp.QuadPart;// 获得初始值
do
{
QueryPerformanceCounter(&litmp);
QPart2 = litmp.QuadPart;//获得中止值
dfMinus = (double)(QPart2-QPart1);
dfTim = dfMinus / dfFreq;// 获得对应的时间值,单位为秒
}while(dfTim<0.001);
其定时误差不超过1微秒,精度与CPU等机器配置有关。 下面的程序用来测试函数Sleep(100)的精确持续时间:
LARGE_INTEGER litmp; 
LONGLONG QPart1,QPart2;
double dfMinus, dfFreq, dfTim;
QueryPerformanceFrequency(&litmp);
dfFreq = (double)litmp.QuadPart;// 获得计数器的时钟频率
QueryPerformanceCounter(&litmp);
QPart1 = litmp.QuadPart;// 获得初始值
Sleep(100);
QueryPerformanceCounter(&litmp);
QPart2 = litmp.QuadPart;//获得中止值
dfMinus = (double)(QPart2-QPart1);
dfTim = dfMinus / dfFreq;// 获得对应的时间值,单位为秒
由于Sleep()函数自身的误差,上述程序每次执行的结果都会有微小误差。下列代码实现1微秒的精确定时:
LARGE_INTEGER litmp; 
LONGLONG QPart1,QPart2;
double dfMinus, dfFreq, dfTim;
QueryPerformanceFrequency(&litmp);
dfFreq = (double)litmp.QuadPart;// 获得计数器的时钟频率
QueryPerformanceCounter(&litmp);
QPart1 = litmp.QuadPart;// 获得初始值
do
{
QueryPerformanceCounter(&litmp);
QPart2 = litmp.QuadPart;//获得中止值
dfMinus = (double)(QPart2-QPart1);
dfTim = dfMinus / dfFreq;// 获得对应的时间值,单位为秒
}while(dfTim<0.000001);
其定时误差一般不超过0.5微秒,精度与CPU等机器配置有关。(完)
posted @ 2008-07-10 12:40 咖啡猪 阅读(95) | 评论 (0)编辑
  2008年7月2日
     前些日子在工作中遇到一个在原子交易中用C#设置系统时间的问题,虽是一个小问题,却因为C#本身没有这种函数而耽误了一些时间,C#要设置系统时间必须要调用Win32的API,而其中相关的函数就是SetSystemTime(), GetSystemTimer(), SetLocalTime(), GetLocalTime(), 这似乎是用VC写的函数,在VC++中是可以直接调用的。MSDN上面对这几个函数解释得不是很详细,网上可以找到不少这样的程序,但我个人感觉对这些函数的功能和注意点说得也不够透彻,包括那个所谓经过测试的。这里把自己所用到的一些功能和体会给出来,至少要把SetSystemTIme()和SetLocalTime()这两个函数的区别搞清楚。

对于这两个函数,其输入参数必须是一个下面这样的结构体,其成员变量类型必须是ushort,成员变量不能改变顺序。

    [StructLayout(LayoutKind.Sequential)]
 public struct SystemTime
 
{
  
public ushort wYear;
  
public ushort wMonth;
  
public ushort wDayOfWeek;
  
public ushort wDay;
  
public ushort wHour;
  
public ushort wMinute;
  
public ushort wSecond;
  
public ushort wMiliseconds;
 }

调用Win32的API,根据需要选用:

 

 public class Win32
 
{
  [DllImport(
"Kernel32.dll")]
  
public static extern bool SetSystemTime(ref SystemTime sysTime );
  [DllImport(
"Kernel32.dll")]
  
public static extern bool SetLocalTime(ref SystemTime sysTime);
  [DllImport(
"Kernel32.dll")]
  
public static extern void GetSystemTime(ref SystemTime sysTime);
  [DllImport(
"Kernel32.dll")]
  
public static extern void GetLocalTime(ref SystemTime sysTime);
 }

下面是SetLocalTime的调用,SetLocalTime的功能就是设置本地系统时间。因为我的工作中要用到的是根据XML文件中的节点内容字符串通过解析后来设置系统时间,所以我做了一个通过输入字符串参数设置本地系统时间的函数,其中调用了SetLocalTime()函数。

 

        public static bool SetLocalTimeByStr(string timestr)
        {
            
bool flag=false;
            SystemTime sysTime 
=new SystemTime();
            
            
string SysTime=timestr.Trim();   //此步骤多余,为方便程序而用直接用timestr即可
            sysTime.wYear = Convert.ToUInt16(SysTime.Substring(0,4));
            sysTime.wMonth 
= Convert.ToUInt16(SysTime.Substring(4,2));
            sysTime.wDay
=Convert.ToUInt16(SysTime.Substring(6,2));
            sysTime.wHour
=Convert.ToUInt16(SysTime.Substring(8,2));
            sysTime.wMinute 
= Convert.ToUInt16(SysTime.Substring(10,2));
            sysTime.wSecond 
= Convert.ToUInt16(SysTime.Substring(12,2));
           
//注意:
            
//结构体的wDayOfWeek属性一般不用赋值,函数会自动计算,写了如果不对应反而会出错
            
//wMiliseconds属性默认值为一,可以赋值
            try
            {
                flag
=Win32.SetLocalTime(ref sysTime);
            }
            
//由于不是C#本身的函数,很多异常无法捕获
           
//函数执行成功则返回true,函数执行失败返回false
           
//经常不返回异常,不提示错误,但是函数返回false,给查找错误带来了一定的困难
            catch(Exception ex1)
            {
                Console.WriteLine(
"SetLocalTime函数执行异常"+ex1.Message);
            }

            
return flag;
        }

如果不是以字符串来赋值,而以int甚至ushort类型数来赋值将会更加简单,不多说了。

程序执行之后本地系统时间将会如期改变。

那么SetLocalTime()和SetSystemTime()又有什么区别呢?大家可以把上述函数的“flag=Win32.SetLocalTime(ref sysTime);”部分换成“flag=Win32.SetSystemTime(ref sysTime);”试试,你将会发现这样一个结果:

执行后系统时间也会改变,但总是比预期的有些偏差,中国的朋友估计都会多出8个小时来。

这是时区的设置造成的,SetSystemTime()默认设置的为UTC时间,当系统设置时间的时候还会按照时区加上一个偏差。而我们的用的北京时间也就是东八区时间,刚好比UTC多了8个小时。这回了解二者的区别了吧。

        这个偏差是不是可以补回来呢?比如对于北京时间,设置完之后减去8个小时就可以了吗?是这么回事,但是具体做起来要有些麻烦,因为要考虑到天,月甚至年都有可能会造成改变,还要考虑到不同的月份。虽然有了SetLocalTime,再来考虑这个有些多此一举,或者也可以直接从时区的方法上入手,但是我偏偏不服,做了一个这样的方法,只是小试一下,没有自己审核,可能会有bug,给大家参考:

        //从字符串设置系统时间
        public bool SetSysTimeByStr(string timestr)