Posts filed under 'WB Editor'
In my article titled Presentation Model in Action, I demonstrated how to the Presentation Model pattern in web site, Windows Forms application and WPF application. Model View View Model pattern is another name of Presentation Model.
On the recently published on the MSDN magazines, there are two articles about using the Model-View-ViewModel (MVVM) pattern in WPF (February, 2009) and Silverlight (March 2009). Maybe on the next issue of MSDN magazine, they will publish another article for using MVVM in ASP.NET. I continue my research to introduce the Dependency Injection and Event Broker into the pattern and have created a new project, named ASP.NET MVVM framework on codeplex.
April 26th, 2009
Visual Studio 2008 isolated mode shell reminds me the Eclipse rich client platform (RCP).
The most important architectural characteristics of Eclipse is the Plug-in architecture, which has concept of Plug-ins, Extensions and Extension-Points.
Plug-ins are the smallest deployable and installable software components of Eclipse. The similar concept in VS is VSPackage. After this eveything began to be very different.
Eclipse plug-ins are pure Java libraries on Java platform.
VS Packages are .NET libraries on COM based on platform through COM interop and MPF.
Eclipse plug-ins are described in XML.
VS replies on registry. VS Packages are using pkgdef and pkgundef files and code attributes.
……
From the Visual Studio 2008 Shell offcial definition:
The Microsoft Visual Studio 2008 Shell provides a core integrated development environment (IDE) to help you build and ship specialized languages and development tools.
Looks like it is only targetting development tools, not general application platform.
What about DSL then? Bound DSL only to VS shell is really limitting the potentials of DSL.
March 9th, 2008
I used to think controller in MVC is to separate the view and the model, until I saw this blog An Introduction to the Model-View-Controller, Model-View-Presenter, and Presentation-Abstraction-Control Patterns where Derek Greer wrote,
One common misconception about the relationship between the MVC components is that the purpose of the Controller is to separate the View from the Model. While the MVC pattern does decouple the application’s domain layer from its presentation layer, this is achieved through the Observer Pattern, not through the Controller. The Controller’s job is to mediate between the human and the application, not between the View and the Model.
While the original idea of the Presenter was seen by the Taligent team as a Controller elevated to an application level, the Dolphin team mistakenly considered it a replacement of the VisualWorks’ Application Model and maintained the Presenter as a mediating component within the triad.
- In MVC, controller is the human to model connector (intercepts user input).
- In Taligent MVP, the presenter is the subsystem component connector (manages application subsystems).
- In Dolphin MVP, the presenter is the presentation to domain connector (manages access to model updates).
- In Passive View, the presenter manages presentation logic.
- In Supervising Controller, the presenter assists with presentation logic.
February 10th, 2008
The code beside technology is used by the visual studio designer. E.g. for each Windows Form, visual studio designer generates two partial classes, one for creating UI elements, and the other one is the place to write code. I think it is a MVP/Passive View already.
- Windows Froms App, The SomeForm.designer.cs is the view and the SomeForm.cs is the presenter.
- ASP.NET, the aspx/ascx is the view and the aspx.cs/ascx.cs is the presenter.
- WPF, the xmal is the view and the xmal.cs is the presenter.
If it Visual Studio generates an interface, ISomeForm.cs. Then have SomeForm.cs reference to this interface, instead of being partial class of the view. It is exactly MVP/Passive View. This would make unit testing easy based on ISomeForm.cs and SomeForm.cs. I would not mind if Visual Studio does this (in fact it might be something good to suggest MS to do).
In SCSF and WCSF, there has to be another presenter class. This makes me feel it is a redundant, because presenter class ties/couples to the view. It can hardly be reused. And you have to create extra code to delegate user input/UI events to the presenter. That’s part of reasons why I am not satisfied w/ MVP in SCSF and WCSF.
The original force of MVP is to ease unit testing. Current unit testing on the presenter is to mock interfaces of view and model. Because there is no other better method, this leaves the mocking on interfaces only one to use practically.
What about to have a tool that generates mock object from aspx/ascx to make aspx.cs/ascx.cs unit test-able?
February 10th, 2008
ASP.NET framework is already a MVC framework that allows to implement MVC.
Within ASP.NET, there is a front controller.
The controller itself is usually implemented in two parts: a handler and a hierarchy of commands. The handler has two responsibilities:
Retrieve parameters. The handler receives the HTTP Post or Get request from the Web server and retrieves relevant parameters from the request.
Select commands. The handler uses the parameters from the request first to choose the correct command and then to transfers control to the command for processing.
The commands themselves are also part of the controller. The commands represent the specific actions as described in the Command pattern [Gamma95]. Representing commands as individual objects allows the controller to interact with all commands in a generic way, as opposed to invoking specific methods on a common command class. After the command object completes the action, the command chooses which view to use to render the page.
The upcoming ASP.NET MVC framework is another front controller implementation.
ASP.NET’s default front controller truns plain http request into view state and server side events. ASP.NET AJAX extended the ASP.NET web form to support partial page render.
ASP.NET MVC replaced (not extended) the default front controller, so that there won’t be view state, nor server side event any more, in order to have SEO/REST style URL. Not sure if it is worth to trade REST style URL with view state, server side events and partial page render.
February 10th, 2008
Here are the slide deck and source code used in my presentation about C# features for fellow developers. Topics include:
C# feature demo: Find even number from a list of integers:
- C# 1.x – Loop in Collection (Array)
- C# 1.x – Delegate (Custom Delegate)
- C# 2.0 – Iterators (yield return)
- C# 2.0 – Delegate (Predicate<T>)
- C# 2.0 – Anonymous Method
- C# 3.0 – Lambda Expression
- C# 3.0 – LINQ (Language integrated Query)
- C# 3.0 – Extended Method
LINQ demo: Match orders with appraisers
- Select: Default, Anonymous Class, Dictionary
- Where: Static, Dynamic Query
- Group: Aggregation, e.g. count
- Join: Inner Join, Out Join, Group Join
- Order: e.g. order by count desc
December 28th, 2007
Too many debates are there about SOAP vs. REST, contract first vs. code first.
But here is my real life experience during developing WB Editor when it needs to connect web services through those famous RESTful style APIs.
First, the API documents usually have no schema definitions other than request and response XML examples. Examples are good for human to read. But after reading, where is the code that I can work with? I have to write code to parse those XML! - This is a pain. If there was schema, machine could generate client code stubs automatically. The nice “Add web reference” way.
Second, maybe the web service providers realized the issue mentioned above. Usually there are client libraries are also available, such as libraries for Java, for .NET, for PHP, for Python and for Javascript …. If using libraries, what is the differece between them to those C libraries ages ago? As long as the the library black box can talk to the server no needs to bother whether underneath it is HTTP, whether it is XML or binary.
I cannot imagine if in my company, when I publishing tones of web services to other departments or clients, I have to also deliver client libraries, for Java, for .NET ….
Tags: WB Editor, SOAP, REST, API, schema, Add web reference, web services
June 8th, 2007
My default SQL CE database was deployed to ClickOnce Data Directory. If changed the database schema, ClickOnce will deploy the new database and keep the old database file (in .pre folder). Here is the psuedo code to migrate schema:
if (IsFirstRun)
{
if (customMigrationORMergeNeeded)
{
string dataFolder = call the API
// Database from V1 of the app
string oldDatabase = Path.Combine(dataFolder,”.pre\db1.db”);
if (File.Exists(oldDatabase))
{
string newDatabase = Path.Combine(dataFolder,”db1.db”);
//perform the task needed with old and new one
DoPerformCustomMigrationORMergeAsNeeded();
}
}
What about removed the program from control panel? Data are all gone.
Looks like better to copy database file to the application data folder.
May 15th, 2007
In IE: open “Tools | Internet Options -> Security”, add the SharePoint sites in “trusted sites”
In firefox: open firefox browse to about:config find “network.automatic-ntlm-auth.trused-uris†modify the value and enter in SharePoint intranet sites that you must pass your username and password to. For some site i connect to i also had to add values to: “network.negotiate-auth.delegation-uris†“network.negotiate-auth.trusted-urisâ€
July 20th, 2006
ç»§ç» VSLive Toronto çš„åŽç»æ•…事。 上次记录了 SQL/e,这次是关于 Daniel Cazzulino çš„å‘言 《Microsoft p&p ObjectBuilder》。å¬å®Œè¿™ä¸ªæ¼”讲å‘现最近周围的事情还都å‘生了些关è”。
首先是日å‰ä¹°äº†æœ¬ä¹¦ 《Head Up Design Patternsã€‹ã€‚å®ƒçš„ç¬¬ä¸€ç« å°±ä»¥ä¸€ä¸ªå¼•äººå…¥èƒœçš„æ•…äº‹ä»‹ç»äº†è®¾è®¡æ¨¡å¼çš„ Strategy Pattern。这个模å¼çš„好处多多,但是负作用是会产生了很多相互关è”的类。如何按照åˆç†åœ°åˆ›å»ºè¿™äº›ç±»ï¼Œå¹¶æŠŠå®ƒä»¬ç»„和起æ¥ã€‚这就引出了å¦å¤–一个è¯é¢˜ Inversion of Control / Dependency Injection。
è¿™å‡ å¤©å¸®å¥³å„¿å¤ä¹ 准备ä¹ç†è€ƒè¯•,还碰到了 Interval Inversion / Triad Inversion,æžå¾—我就很头æ˜ã€‚Dependency Injection 好åƒè¿˜å¥½ç†è§£äº›ã€‚
Daniel Cazzulino 讲的 ObjectBuilder 就是一个具有 dependency injection 功能的轻é‡çº§å¯¹è±¡å®¹å™¨*。 ObjectBuilder 是 ï¼ï¼³ patterns & practices Composite UI Application Block ä»¥åŠ Enterprise Library çš„æ ¸å¿ƒéƒ¨åˆ†ã€‚
这就åˆå¼•到了 CAB - Composite UI Application Block。也是ä¸ä¹…å‰ WB Editor 3.0 的设计已ç»å¼€å§‹äº†ã€‚鉴于 2.0 ç‰ˆæœ¬ä¸ RAD æµæ¯’太深**,决定应该采用个好的系统结构,æ£åœ¨çŠ¹è±«ï¼Œæ˜¯å¦ç”¨è¿™ç¯‡ Implement a Microsoft Word-like Object Model for Your .NET Framework Application æ–‡ç« ä»‹ç»çš„æ–¹æ³•呢,还是用 CAB。
ç»è¿‡è†å¬ Daniel Cazzulino 的讲解,ä¸ä½†äº†è§£äº† OB çš„åŠŸèƒ½ï¼Œè¿˜äº†è§£äº†å…¶å†…éƒ¨çš„ä¸€äº›æœºåˆ¶ã€‚å› æ¤å†³å®šè¿›ä¸€æ¥å¦ä¹ 了一下 CAB Hands on Lab。于是得到结论就是 WB Editor 3.0 将采用 CAB。
Daniel Cazzulino 还讲了个有用的内容,Guidance Automation Toolkit / GAT,值得å†ç”¨ä¸€ç¯‡ç¬”记介ç»ã€‚
* è½»é‡çº§å¯¹è±¡å®¹å™¨å’Œ ** RAD æµæ¯’也å¯ä»¥è®²äº›æ•…事。
Tags: VSLive ObjectBuilder Strategy Pattern Inversion of Control Dependency Injection Composite UI Application Block CAB RAD
May 14th, 2006
During the WB Editor 2.5 testing, we found an interesting concurrency control issue. In this version, we allowed multiple program instance for ease of cross posting.
Now in multiple instance windows, user can setup blog server accounts differently. Which one is the winner?
“Last one wins” was disapproved by QA.
Maybe we need optimistic concurrency. I this case user will receive a dialog saying “another instance has modified the settings”, do you want to overwrite or discard or reload?
Another option is concurrency control with change notifications. Using FileSystemWatcher to detect changes of configuration file, but what should happen next in UI?
Tgas: WB Editor concurrency control Last one wins optimistic change notifications multiple instance blog cross posting FileSystemWatcher
May 10th, 2006
剿–‡æè¿°äº†.NET 为 Shareware 程åºå¼€å‘æä¾›äº†è®¸å¯è¯æ£€æµ‹æœºåˆ¶ï¼Œä½¿å¾—å¼€å‘者å¯ä»¥é›†ä¸ç²¾åŠ›åˆ°å¦‚ä½•éªŒè¯è®¸å¯è¯ã€‚
把一个信æ¯ç»ç”±ä¸å¯ä¿¡ä»»çš„é€”å¾„ä¼ è¾¾ç»™æŽ¥å—者的时候,就需è¦è¿›è¡ŒåŠ å¯†ã€‚å¯¹äºŽä¿¡æ¯æŽ¥å—者æ¥è¯´ï¼Œåˆ™éœ€è¦ç¡®è®¤ä¿¡æ¯çš„æ¥æºæ˜¯æ¥è‡ªæ£ç¡®çš„,就需è¦è¿›è¡Œæ•°å—ç¾å。Shareware ç¨‹åºæ‹¥æœ‰è€…è¦å‘Šè¯‰è¿œåœ¨ç”¨æˆ·æœºå™¨ä¸Šçš„自己的程åºç”¨æˆ·æœ‰æƒä½¿ç”¨è¿™ä¹ˆä¸ªä¿¡æ¯ï¼Œæ˜¯è¦åŠ å¯†çš„ã€‚å› ä¸ºä½ ä¸æƒ³è®©å…¶ä»–人知é“è¿™ä¸ªä¿¡æ¯æ˜¯å¦‚何表达的,更ä¸èƒ½è®©äººå®¶å¦‚法炮制出相åŒçš„ä¿¡æ¯ã€‚
.NET æä¾›äº†åŠ å¯†å’Œæ•°å—ç¾åç‰çŽ°åœ¨ç”¨åœ¨ç½‘ç»œå®‰å…¨æ–¹é¢çš„æŠ€æœ¯ç”¨åˆ° Shareware 上是ç»å¯¹å¥½çš„ã€‚ä¸‹é¢æ˜¯ç”¨ .NET RSACryptoServiceProvider 的一个办法。
RSA 是一ç§éžå¯¹ç§°åŠ å¯†æŠ€æœ¯ Asymmetric Cryptography,å³åŠ å¯†ç”¨çš„å¯†ç å’Œè§£å¯†ç”¨çš„å¯†ç æ˜¯åˆ†å¼€ï¼Œç›¸äº’ä¸èƒ½æŽ¨æ¼”的。如果知é“了解密用的密ç ï¼Œæ— æ³•çŸ¥é“åŠ å¯†ç”¨çš„å¯†ç ã€‚è¿™æ¯”å¯¹ç§°åŠ å¯†å®‰å…¨æ€§å¥½ï¼Œå› ä¸º Shareware 总是需è¦ä¸€ä¸ªå¯†ç 用æ¥è§£æ³¨å†Œç ï¼Œç”¨å¯¹ç§°åŠ å¯†çš„æƒ…å†µä¸‹ï¼Œå¦‚æžœè¢«äººä»Žç¨‹åºä¸åˆ†æžåˆ°äº†è§£å¯†çš„密ç ,有å¯èƒ½å¤åˆ¶æ³¨å†Œæœºã€‚而用éžå¯¹ç§°åŠ å¯†ï¼Œå³ä½¿è§£å¯†çš„å¯†ç æ³„æ¼ï¼Œä¹Ÿæ— 法åšå‡ºæ³¨å†Œæœºã€‚
1ã€ç”Ÿæˆå’Œä¿å˜å¯†ç
创建个新的 RSACryptoServiceProvider 对象,.NET å°±éšæœºç”Ÿæˆäº†å¯†ç 。
RSACryptoServiceProvider 对象å¯ä»¥æŠŠå¯†ç è¾“å‡ºæˆ xml。
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
Console.WriteLine(rsa.ToXmlString(true));
这个 xml 是è¦å¥½å¥½ä¿å˜èµ·æ¥çš„秘密。其ä¸åŒ…å«äº†ç”¨æ¥åšæ³¨å†Œæœºçš„åŠ å¯†ç”¨çš„ private key å’Œ å°†æ¥åœ¨ç¨‹åºä¸ç”¨æ¥è§£å¯†çš„用 public key。
<RSAKeyValue>
<Modulus>…</Modulus>
<Exponent>…</Exponent>
<P>…</P>
<Q>…</Q>
<DP>…</DP>
<DQ>…</DQ>
<InverseQ>…</InverseQ>
<D>…</D>
</RSAKeyValue>
2ã€æ³¨å†Œæœº
æ ¹æ®ä¸Šé¢çš„密ç xml,å¯ä»¥è¿™æ ·ç”Ÿæˆæ³¨å†Œæœºæ‰€éœ€è¦çš„ RSACryptoServiceProvider 对象。然åŽç”¨æ•°å—ç¾åçš„åŠžæ³•ç”Ÿæˆæ³¨å†Œç 。
SignData æ˜¯åšæ•°å—ç¾å。它与å•çº¯çš„åŠ å¯†è§£å¯†æœ‰åŒºåˆ«ã€‚
如果è¦å˜æˆæ³¨å†Œç æ˜¯è¿™æ ·ä¸€å¥è¯ï¼šæŸäººäºŽæŸæ—¶æŸåœ°è´ä¹°äº†æˆ‘的软件。å•çº¯çš„åŠ å¯†åŽçš„è§£å¯†ä½ ä¼šçœ‹åˆ°è¿™å¥åŽŸè¯(从内å˜é‡Œä»€ä¹ˆåœ°æ–¹æŒ–出æ¥)。而用数å—ç¾å办法,解密åŽçœ‹ä¸åˆ°åŽŸè¯ï¼Œè€Œæ˜¯ä¸€ä¸ªå•å‘计算出æ¥çš„ Hash å€¼ã€‚æ‰€ä»¥å¯¹æ‰€ä¼ é€çš„ä¿¡æ¯å¤šäº†ä¸€å±‚ä¿æŠ¤ã€‚RSACryptoServiceProvider æä¾›äº†ç›´æŽ¥çš„ç”Ÿæˆæ•°å—ç¾åå’ŒéªŒè¯æ•°å—ç¾å的方法。
private static byte[]CreateKey()
{
byte[] digestInput = fileEncoding.GetBytes(GetRegistrationInfo());
RSACryptoServiceProvider RSAalg= new RSACryptoServiceProvider();
RSAalg.ImportParameters(GetPrivateKeyParam());
return RSAalg.SignData(digestInput, new SHA1CryptoServiceProvider());
}
private static string GetRegistrationInfo()
{
return GetValue(“NAME”)+GetValue(“PURCHASE_TIME”)+GetValue(“FROM”);
}
private static RSAParametersGetPrivateKeyParam()
{
RSAParameters param = new RSAParameters();
param.D= Convert.FromBase64String(“…”);
param.DP = Convert.FromBase64String(“…”);
param.DQ = Convert.FromBase64String(“…”);
param.Q = Convert.FromBase64String(“…”);
param.P = Convert.FromBase64String(“…”);
param.Exponent= Convert.FromBase64String(“…”);
param.Modulus= Convert.FromBase64String(“…”);
param.InverseQ= Convert.FromBase64String(“…”);
return param;
}
从 XML ä¸ç”Ÿæˆ private key æ¥åˆ¶ä½œæ•°å—ç¾å,需è¦ç”¨åˆ°å…¨éƒ¨å‚数:D, DP, DQ, P, Q, Exponent, Modulus, InverseQ.
3ã€éªŒè¯æ•°å—ç¾å
在 Shareware 程åºä¸ï¼Œä»Žå¯†ç xml 文件生æˆéªŒè¯æ•°å—ç¾å所需è¦çš„ SACryptoServiceProvider 对象,然åŽè¯·ç”¨æˆ·è¾“入他的åå—ã€ä»¥åŠè´ä¹°è½¯ä»¶çš„æ—¶é—´åœ°ç‚¹ã€‚组æˆä¸€ä¸ªå¥å:æŸäººäºŽæŸæ—¶æŸåœ°è´ä¹°äº†æˆ‘的软件,用 SACryptoServiceProvider 验è¯ä¸€ä¸‹å®ƒçš„æ•°å—ç¾å是å¦ç¬¦åˆæ³¨å†Œæœºç”Ÿæˆæ³¨å†Œç 。
private static bool VerifyKey(byte[]digestInput, byte[] signed)
{
RSACryptoServiceProviderRSAalg = new RSACryptoServiceProvider();
RSAalg.ImportParameters(GetPublicKeyParam());
return RSAalg.VerifyData(digestInput, new SHA1CryptoServiceProvider(),signed);
}
private static RSAParametersGetPublicKeyParam()
{
RSAParameters param = new RSAParameters();
param.Exponent = Convert.FromBase64String(“…”);
param.Modulus = Convert.FromBase64String(“…”);
return param;
}
从 XML ä¸ç”Ÿæˆ public key æ¥éªŒè¯æ•°å—ç¾å,åªè¦ç”¨ä¸¤ä¸ªå‚数:Exponent, Modulus. 别人å³ä½¿ä»Žä½ æ•£å‘å‡ºåŽ»çš„ç¨‹åºæœ¬èº«ç ´è§£å¾—到了public key,没有其它多大用处。
å½“ç„¶ï¼Œç ´è§£ä¸ä»…仅是è¦å¾—到密ç 。如果æ¥ä¸ªæš´åŠ›ç ´è§£ï¼ŒæŠŠä½ çš„ç¨‹åºå编译出æ¥ï¼ŒæŠŠä½ çš„ public key æ¢æˆä»–的,与他自己的注册机é…åˆçš„ï¼Œé‚£ä½ ä¸å°±è¢«æŠ¢åŠ«ä¸€ç©ºäº†ï¼Œæˆ–è€…å编译出æ¥åˆ æŽ‰å‰æ–‡æ‰€è¿°çš„ LicenseProvdier,或者 …….,还有很多办法。
.NET æä¾›çš„许å¯è¯ç›‘测机制,éžå¯¹ç§°åŠ å¯†æ˜¯å¦èƒ½çœŸæ£å‘æŒ¥ï¼Œè¿˜å¾—çœ‹ç¨‹åºæœ¬èº«çš„åŠ æ‰°ç¨‹åº¦ã€‚ä¸‹ä¸€ç¯‡æ–‡ç« ä»‹ç»ã€‚
Tags: shareware asymmetric cryptography rsa private key public key
March 16th, 2005
制作 Shareware 有三个关键点:
- å¦‚ä½•ä¿æŠ¤å¯¹è±¡(程åº),在创建对象的时候检测许å¯è¯ (License)。
- åŠ å¯†/解密 用户信æ¯å’Œæ³¨å†Œä¿¡æ¯ã€‚
- 程åºåŠ æ‰° (obfuscate) 或者程åºåŠ å¯†ï¼Œåç ´è§£ã€‚
.NET 为å‰ä¸¤è€…æä¾›äº†åŸºæœ¬æ”¯æŒï¼Œéžå¸¸æ–¹ä¾¿ã€‚这里先说检测许å¯è¯ã€‚许å¯è¯å¯ä»¥æœ‰é€šç”¨æ³¨å†Œç ã€éªŒè¯ç”¨æˆ·å的注册ç ã€éªŒè¯ç”¨æˆ·æœºå™¨çš„æ³¨å†Œç ç‰å½¢å¼ã€‚当用户花钱è´ä¹°äº† Shareware 程åºï¼ŒShareware ç¨‹åºæ‹¥æœ‰è€…就会å‘逿³¨å†Œç 给用户。(Share-It 有在线注册ç 生æˆåŠŸèƒ½ï¼Œä¸€æ”¶åˆ°é’±ç«‹å³è‡ªåŠ¨ç”Ÿæˆæ³¨å†Œç )。
Shareware 程åºè¿è¡Œæ—¶è¦æ£€æµ‹å’ŒéªŒè¯ç”¨æˆ·æ˜¯å¦å…·æœ‰æœ‰æ•ˆçš„æ³¨å†Œç ,以决定用户是å¦èƒ½æ‰§è¡Œç¨‹åºã€‚
.NET 下的程åºéƒ½æ˜¯é¢å‘对象的,所以 .NET 在对象的创建机制上,æä¾›äº†è®¸å¯è¯æ£€æµ‹çš„一个接å£ï¼ŒShareware 程åºå¼€å‘å¯ä»¥åœ¨æ¤åŸºç¡€ä¸ŠåŠ å…¥è‡ªå·±çš„æ³¨å†Œç 验è¯ç®—法。
.NET Licensing 一文介ç»äº†è®¸å¯è¯æ£€æµ‹çš„办法:
[LicenseProviderAttribute(typeof(LicFileLicenseProvider))]
public class LicensedClass : IDisposable
{
private License license = null;
public LicensedClass()
{
license = LicenseManager.Validate(typeof(LicensedClass), this);
Console.WriteLine(“Hello from the licensed class.”);
}
public void Dispose()
{
if (license != null)
{
license.Dispose();
license = null;
}
}
}
有了这么个结构,程åºå¼€å‘å¯ä»¥æŠŠæ£€æµ‹è®¸å¯è¯äº¤ç”± .NET 完æˆï¼Œè€Œè‡ªå·±é›†ä¸ç²¾åŠ›è®¾è®¡å¦‚ä½•éªŒè¯æ³¨å†Œç 。把上é¢çš„ LicFileLicenseProvider æ¢æˆè‡ªå·±çš„ Custom LicenseProvider。比如,ä¸è¯»æ–‡ä»¶è€ŒåŽ»è¯»æ³¨å†Œè¡¨ï¼Œè§ï¼šCodeGuru: Licensed Applications using the .NET Framework ã€‚æˆ‘çš„ä¸€äº›æ–‡ç« æ”¶è— (RSSæ ¼å¼) 。
ä¸è®ºæ˜¯ä»Žæ–‡ä»¶æˆ–者从注册表得到注册ç ,它包å«äº†æˆ·æ˜¯å¦å¯ä»¥è¿è¡Œç¨‹åºçš„ä¿¡æ¯ï¼Œè€Œä¸”它一定是åªèƒ½ Shareware ç¨‹åºæ‹¥æœ‰è€…è¯´äº†ç®—ã€‚å› æ¤è¿™ä¸ªä¿¡æ¯æ˜¯å¿…é¡»åŠ å¯†çš„ã€‚
.NET æä¾›äº†éžå¯¹ç§°åР坆 (Asymmetric Cryptography) 工具å¯ä»¥ç”¨æ¥å¤„ç†æ³¨å†Œç ã€‚ä¸‹ä¸€ç¯‡æ–‡ç« é‡Œç»§ç»ä»‹ç»ã€‚
March 3rd, 2005
éšç€ WB Editor 2 çš„å‘布,它æå‡ºçš„å£å·æ˜¯ï¼š Blogging is not just editing and posting. Feel the fun and the power with WB Editor 2.
在 å†è®® WB Editor æ’ä»¶ ä¸€æ–‡ä¸æåˆ°äº†ä¸å°‘æµè§ˆå™¨æ— æ³•å®žçŽ°çš„åŠŸèƒ½ã€‚è¿™é‡Œå†æ¯”较一下å³ä½¿æµè§ˆå™¨ä¹Ÿç”¨ä¸Šäº† htmlarea, FreeTextBox, CuteEditor, FCKEditor ç‰ç¼–辑器,也ä¸èƒ½è¾¾åˆ° WB Editor æä¾›çš„é‚£ç§ç»†è‡´ç¨‹åº¦ã€‚
1ã€å¿«é€Ÿæ ¼å¼æ–‡æœ¬
Wiki é‡Œé¢æœ‰ä¸€æ´¾è§‚点是 WYSIWYG 是ä¸åˆ©çš„,å†é‡ç‚¹åœ¨å†™ä½œè€Œä¸æ˜¯æŽ’版的人眼里,排版打æ–了创作的æ€è·¯ã€‚å› æ¤ï¼ŒWiki 使用了 Textile é£Žæ ¼çš„æŽ’ç‰ˆã€‚WB Editor åœ¨ä¸»è¦æ”¯æŒ WYSIWYG ç¼–è¾‘çš„åŒæ—¶ï¼Œä¹Ÿé€šè¿‡ Quick Format æ’ä»¶æ¥å®žçް Textile 的排版功能。 类似的功能也å¯ä»¥åœ¨ word 2003 里é¢çœ‹åˆ°ã€‚
*åŠ ç²—*〠_斜体_ æŒ‰å¿«é€Ÿé”®å°±å˜æˆäº†ï¼š åŠ ç²—ã€ æ–œä½“
2ã€å¤„ç†è¿žæŽ¥ (hyperlink)
æŠŠæ™®é€šæ–‡æœ¬å˜æˆè¶…æ–‡æœ¬ï¼ŒåŠ å…¥è¿žæŽ¥çš„è¿‡ç¨‹å¾ˆæ˜¯ç¹ç。WB Editor 有三ç§åŠžæ³•æ¥ç®€åŒ–它,都是æµè§ˆå™¨ä¸å¯èƒ½åšåˆ°çš„。
- 一是 Add link å¯¹è¯æ¡†å…·æœ‰ Auto-Complete 的功能,就如åŒåœ¨ IE åœ°å€æ 里输入地å€ï¼Œéšç€è¾“入,它从æµè§ˆåކå²ä¸æ‰¾å‡ºç›¸è¿‘çš„ URL。
- 二是 Textile é£Žæ ¼çš„å¿«é€Ÿæ ¼å¼åŒ–,能把 “WB Editor”:http://www.wbeditorï¼Œæ ¼å¼åŒ–æˆï¼š<a href=”http://www.wbeditor.com”>WB Editor</a>。
- 三是 Hyperlink Wizard æ’ä»¶ï¼Œå®ƒèƒ½è¯†åˆ«æ–‡ç« ä¸çš„连接,ä¿å˜ä¸‹æ¥ï¼ŒæŒ‰ä¸ªå¿«é€Ÿé”®å°±èƒ½åˆ†æžæ–‡ç« ï¼Œè‡ªåŠ¨åŠ ä¸Šè¿žæŽ¥ã€‚
3ã€HTML 过滤
如果从网页上å¤åˆ¶æ–‡å—ã€å›¾ç‰‡è¿› WYSIWYG HTML 编辑器,在ä¿ç•™äº†æŽ’ç‰ˆå’Œè¿žæŽ¥çš„åŒæ—¶ï¼Œä¸€äº›æ²¡æœ‰ç”¨çš„ DHTML 属性甚至 Javascript 也被带了进æ¥ã€‚比如,从 google 网页å¤åˆ¶ä¸ªæ£€ç´¢ç»“æžœ WB Editor the desktop blogging tool 过æ¥ï¼Œå®ƒçš„ HTML 是
<A onmousedown=”return clk(this,’res’,1)” href=”http://www.wbeditor.com/”><FONT color=#551a8b><B>WB</B> <B>Editor</B> the desktop blogging tool</FONT></A>。
WB Editor çš„ HTML Cleaner å°±èƒ½æ¸…é™¤é‚£äº›æ— ç”¨çš„ã€ç”šè‡³å±é™©çš„ HTML Tag (form, iframe, script, input ….) å’Œ HTML 事件属性 (onload, onclick, id …),尤其是 id,如果从 ASP.NET 网页å¤åˆ¶çš„东西,会带æ¥ä¸€å¤§å †èŽ«å其妙的 id 属性。这下全部被 WB Editor 过滤掉了。
4ã€å›¾åƒå¤„ç†
与æ’入连接类似,æ’å…¥å›¾ç‰‡åˆ°æ–‡ç« ä¸ä¹Ÿæ˜¯éžå¸¸éº»çƒ¦çš„一件事情。WB Editor 的图片上载使得æ’图æˆä¸ºä¸€ä»¶å¾ˆæœ‰æ„æ€çš„事情,它å¯ä»¥åˆ›å»ºç¼©ç•¥å›¾ã€å¹¶åœ¨ç¼©ç•¥å›¾ä¸ŠåŠ ä¸Šå…¨å›¾çš„è¿žæŽ¥ã€‚è¿™ä¸ªç”¨ GDI+ 实现的缩图功能,使得 blog æ–‡ç« å…·æœ‰äº†å…¨æ–°çš„é¢è²Œï¼Œçœ‹èµ·æ¥æ›´åŠ ç²¾è‡´ï¼Œè±¡ Windows 程åºç•Œé¢è®¾è®¡é…é…¿ä¸çš„å˜é© 一文。(Wordpress, .Text ç›®å‰ä¸æ”¯æŒå›¾ç‰‡ä¸Šè½½ã€‚支æŒå›¾ç‰‡ä¸Šè½½çš„æœåŠ¡å™¨æœ‰ï¼šMovable Typeã€Drupal 4.5ã€Nucleus … )
用 WB Editor 写 blog 的过程ä¸å¯ä»¥æ…¢æ…¢ä½“会到那些æµè§ˆå™¨ä¸å¯èƒ½æä¾›çš„功能和ä¹è¶£ã€‚这就是WB Editor å£å·çš„å«ä¹‰ã€‚这个å«ä¹‰åœ¨ä»¥ä¸Šçš„四点ä¸è¿˜åªä½“现出æ¥äº†ä¸€ç‚¹ç‚¹ï¼Œä»¥åŽè¿˜ä¼šç”¨å…¶å®ƒæ–‡ç« æ¥ä»‹ç»ã€‚
November 10th, 2004
2004 å¹´ 7 月 MSDN çš„ IUIs and Web-Style Navigation in Windows Forms, Part 1 ç»“åˆæœ€è¿‘å¼€å‘ WB Editor 的实践,引å‘了我对 Windows 程åºç•Œé¢è®¾è®¡çš„一些新感想。
WB Editor 是个典型的 Windows 程åºã€‚在开å‘è¿‡ç¨‹ä¸æ€»æ˜¯æ„Ÿè§‰å®ƒçš„界é¢ä¸å¯¹åŠ²ï¼Œå®ƒåº”è¯¥é¢å‘最普通的计算机用户,而实际上它的界é¢å´æ˜¯ä»¤äººæœ›è€Œç”Ÿç•的。
é˜…è¯»é‚£ç¯‡æ–‡ç« åŽæ„Ÿè§‰å®ƒä¸º WB Editor 的界é¢é—®é¢˜æä¾›äº†ä»ŠåŽå¼€å‘的方å‘,那就是 Web-Style。 按照上文,MS æ£åœ¨æŠŠ Web-Style Navigation 的支æŒåšåˆ° Avalon (Longhorn 的显示部分) 里é¢ã€‚WB Editor 2.0 çš„ç›®æ ‡ä¹‹ä¸€ä¹Ÿå°±å°è¯•是 Web-Style Navigation。
我预计从现在开始,会看到越æ¥è¶Šå¤š Windows 程åºç•Œé¢è®¾è®¡å¤§é‡é‡‡ç”¨ Web-Style,这就是我所说的é…é…¿ä¸çš„å˜é©ã€‚
November 10th, 2004
æ›¾ç»æœ‰äººé—®ï¼Œå†™ blog 用æµè§ˆå™¨è¶³å¤Ÿäº†ï¼Œä¸ºä»€ä¹ˆè¿˜è¦ WB Editor è¿™æ ·çš„å·¥å…·ï¼Ÿ
ç”æ¡ˆå¾ˆç®€å•,WB Editor æä¾›äº†æµè§ˆå™¨æ— 法æä¾›çš„功能。
试想在用 WB Editor 写作的时候,
- å¯ä»¥ç”¨ webcam æ‹å¼ 照片,æ’å…¥æ–‡ç« ã€‚
- å¯ä»¥éšæœºæ’入一个å言è¦å¥ã€‚好好å¦ä¹ ,天天å‘上 :-)。
- å¯ä»¥æŽ¥é©³ GPS,把过去走过的路线下载到 blog 里é¢ã€‚
- å¯ä»¥å¤åˆ¶äº›æ–‡å—,å‘个手机çŸä¿¡ã€‚
- ……
自从 WB Editor 有了æ’件支æŒï¼Œåšäº›éƒ½ä¸å†æ˜¯é¥è¿œçš„æ¢¦æƒ³ã€‚
çŽ°åœ¨å·²ç»æœ‰äº†æ’ä»¶åšè¯æ³•检查ã€å¿«é€ŸæŽ’版ã€ä»£ç åŠ äº®ã€‚æ–°è¿‘è¿˜å®Œæˆäº†ä¸ªæ’件,å¯ä»¥ç”¨æ¥ç®¡ç†(自定义)所有æ’件的快æ·é”®ï¼Œæ£åœ¨åˆ¶ä½œ FTP æ’ä»¶(用æ¥ä¸Šä¼ 文件)ã€è¿žæŽ¥åˆ†æžæ’ä»¶(æå–ã€ä¿å˜æ–‡ç« ä¸çš„è¿žæŽ¥ï¼Œè‡ªåŠ¨åŠ è¿žæŽ¥) ……
çœŸæ˜¯ä¸æ€•åšä¸åˆ°ï¼Œåªæ€•想ä¸åˆ°ã€‚
有了这些æ’件,为写 blog å¢žæ·»æ— æ•°çš„ä¹è¶£ã€‚
November 10th, 2004
BlogJet 的作者 Dmitry Chestnykh 和我打算建立一个关于 blog 客户端工具的 Wikiã€‚ç½‘å€æ˜¯ blogclients.info 。我å¯ä»¥åœ¨é‚£é‡Œä»‹ç» WB Editor。
blog 客户端工具的境地ååˆ†å¥‡ç‰¹ï¼Œå®ƒèƒŒè´Ÿç€ blog æœåС噍 bug 的黑锅。
对于 blog æœåС噍æ¥è¯´ï¼Œweb ç•Œé¢æ˜¯ä¸»è¦çš„,xml-rpc æ”¯æŒæ˜¯æ¬¡è¦çš„,很多系统的 xml-rpc 错误百出。 WB Editor Knowledge Base 收录了很多æœåС噍æ–çš„é”™è¯¯ã€‚ä¸ºäº†ç ”ç©¶ blog æœåŠ¡å™¨çš„é—®é¢˜ï¼Œæˆ‘éƒ½å¿«æˆ PHP 专家了。
blog æœåŠ¡å™¨çš„ xml-rpc 支æŒè¿˜ä¼šå˜åŒ–,donews å…³é—了 .Text 系统的 blog 部分,blogger.com çš„ utf-8 支æŒå掉了ç‰ç‰æƒ…况,用户第一个抱怨的是 blog 客户端工具ä¸å·¥ä½œäº†ã€‚还很难解释。
November 10th, 2004
WB Editor å¯ä»¥é€šè¿‡æ’ä»¶å¯ä»¥ä¸°å¯Œå…¶åŠŸèƒ½ã€‚æ¯”å¦‚ï¼Œæ‹¼å†™æ£€æŸ¥ã€Wiki 排版ã€è¯æ³•åŠ äº®æ’ä»¶ç‰ç‰ã€‚WB Editor æ’件是外挂的软件模å—ã€‚å®ƒç¼–è¯‘æˆ DLL 的形å¼ï¼Œå½“把它放到 WB Editor çš„è¿è¡Œç›®å½•,WB Editor 能自动识别它。
WB Editor æ’件是一个实现了 IWBEditorPlugIn 接å£çš„类。
public interface IWBEditorPlugIn
{
string GetPluginName();
string[] GetCommands(string parentCommand);
int QueryStatus(string name);
void ExecuteCommand(string name);
}
WB Editor å¯åŠ¨çš„æ—¶å€™è‡ªåŠ¨æ‰«æç¨‹åºè¿è¡Œç›®å½•下é¢çš„æ‰€æœ‰ DLL,查找实现了 IWBEditorPlugIn 接å£çš„类。找到åŽåЍæ€è½½å…¥æ’件类,调用它的 GetPluginName 方法查询æ’ä»¶å称,并把这个å称显示在 Plugin èœå•下é¢ã€‚接ç€ç»§ç»ç”¨ GetCommands æ¥æŸ¥è¯¢æ’件命令å称,并把它们显示在æ’ä»¶åç§°èœå•下é¢ã€‚这就实现了一个æ’件多个命令的功能。GetCommands å¯ä»¥è¿”回 null,表示没有命令,而æ’ä»¶åç§°å°±æˆä¸ºå”¯ä¸€çš„命令。
如果用户点击了æ’ä»¶èœå•,WB Editor 就调用 ExecuteCommand æ¥æ‰§è¡Œç”¨æˆ·é€‰æ‹©çš„命令。这时候程åºè¿è¡Œçš„æŽ§åˆ¶æƒå°±äº¤åˆ°æ’件手里了。
那么,æ’件有怎么控制 WB Editor 呢?这就需è¦ç”¨åˆ° WBEditorService 类了。WB Editor 一开始è¿è¡Œï¼Œå°±å·²ç»é¢„å…ˆåˆå§‹åŒ–好了 WBEditorService, æ’ä»¶å¯ä»¥
- 用 WBEditorService.GetEditorContent 获å–编辑器ä¸çš„内容。
- 用 WBEditorService.SetEditorContent 设置新的编辑内容。
- 用 WBEditorService.GetSelection 获å–编辑器被选ä¸çš„内容。
- 用 WBEditorService.InsertText å‘ç¼–è¾‘å™¨ä¸æ’入内容。
- è¿˜æœ‰ä½œæ–‡å—æ›¿æ¢çš„函数ã€èŽ·å– COM IHTMLElement,IHTMLDocument,RSS Item XmlDocument ç‰ç‰çš„高级功能函数。
WB Editor æ’ä»¶æŽ¥å£æ ‡å‡†å’Œå‚考程åº: http://www.wbeditor.com/content/view/34/44
WB Editor æ’ä»¶å¯ä»¥ç”¨ C#, VB.NET 或者 Delphi 8 æ¥åšï¼Œå› 为是 .NET 一家å嘛。
åšæ³•是:
1.创建一个 Class Library,Add reference IWBEditorPlugIn.dll
2.创建一类实现 IWBEditorPlugIn 接å£ï¼Œä»¥åŠæ’件的功能。
3.编译åŽï¼ŒæŠŠå¾—到的 DLL å¤åˆ¶åˆ° WB Editor è¿è¡Œç›®å½•ä¸‹ã€‚é‡æ–°è¿è¡Œ WB Editor,就能看到 Tools | Plugins èœå•下有新的æ’件了。
有兴趣者欢迎试试。
November 10th, 2004
WYSIWYG 编辑器
WB Editor çš„æ ¸å¿ƒæ˜¯å¤§å鼎鼎的 Nikhil Kothari çš„ HtmlEditor Control,它什么都好就是载入内容到编辑器去的方法是错的。它生æˆçš„ stream 䏿”¯æŒä¸æ–‡ã€‚äºŽæ˜¯æˆ‘æ”¹è¿›äº†å®ƒï¼Œä¸æ–‡ã€æ—¥æ–‡æ²¡æœ‰é—®é¢˜äº†ã€‚但是,如果 IE Encoding 用 UTF8,WB Editor å¯èƒ½ä¸æ–‡å‡ºä¹±ç ã€‚åŽæ¥åœ¨ http://www.itwriting.com/htmleditor çš„ htmleditor 䏿‰¾åˆ°äº†åˆ›å»º unicode stream çš„æ£ç¡®åŠžæ³•ï¼Œè¿˜å®žçŽ°äº†å°åº¦æ–‡æ”¯æŒã€‚
xhtml
WB Editor æ— æ³•è¿žæŽ¥ b2evoï¼Œå› ä¸º b2evo è¦æ±‚输入为 xhtml。逼得我从 dasBlog 䏿Œ–掘出了个html formatting 工具包,也是 Nikhil Kothari 的作å“。
安装程åº
原先用 MAKEMSI 工具åšçš„ WB Editor å®‰è£…ç¨‹åºæœ‰ä¸ªç¼ºç‚¹ï¼Œå°±æ˜¯æ— 法检测并æé†’用户去下载安装 .NET Framework。以至于ä¸çœ‹ readme.txt 的用户ä¸çŸ¥é“这一先决æ¡ä»¶ã€‚å—到 WiX for dummies 一文的å¯å‘,找到了个办法: 找æ¥åŽŸå§‹çš„ wbeditor.msiï¼Œå†æ‰¾æ¥ä¸€ä¸ªèƒ½æ£€æµ‹ .NET çš„ msi 。两个 msi 都用 wix åç¼–è¯‘å‡ºæ¥ (用其 dark /x 工具),然åŽï¼ŒæŠŠå¾—到的两个 wix xml 文件巧妙地和并起æ¥ï¼Œæœ€åŽç”¨ candle å’Œ light 工具釿–°ç¼–è¯‘ç”Ÿæˆæ–°çš„ msi。
HTML è¯æ³•åŠ äº®
å‚考了很多资料,总算åšå‡ºäº†ä¸€ä¸ªä¸é—ªçƒçš„ html åŠ äº®ç¼–è¾‘å™¨ã€‚ä½†æ˜¯è‡ªå·±éžå¸¸ä¸æ»¡æ„:相应速度ä¸å¥½ï¼Œæ²¡æœ‰ä»£ç æç¤ºã€è‡ªåŠ¨å®Œæˆã€æ²¡æœ‰ as you type è¯æ³•æ£€æŸ¥ã€‚å‡†å¤‡æœ‰ç©ºç ”ç©¶ç ”ç©¶ SharpDevelop 里的编辑器。
æ’件技术
妿–‡è¯¦ç»†ä»‹ç»ã€‚
November 10th, 2004