<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>comp.lang.Ken-LIU</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/kenliu/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/kenliu/feed.xml</link>
    <description>This is Ken. This is everything about computer languages, programming skills and thinking of technologies. It records my knowledge reviews, techniques exploring and researching.</description>
    <lastBuildDate>Tue, 16 Apr 2019 06:11:47 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Happy 100 days birth!</title>
      <link>https://docs.microsoft.com/archive/blogs/kenliu/happy-100-days-birth</link>
      <pubDate>Fri, 23 Jan 2009 04:59:00 GMT</pubDate>
      <dc:creator><![CDATA[TechNet Archive]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/kenliu/2009/01/23/happy-100-days-birth/</guid>
      <description><![CDATA[For my little baby boy!
baby.pdf]]></description>
      <content:encoded><![CDATA[For my little baby boy!
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/telligent.evolution.components.attachments/01/5892/00/00/03/19/07/05/baby.pdf" original-url="https://blogs.technet.com/cfs-filesystemfile.ashx/__key/telligent-evolution-components-attachments/01-5892-00-00-03-19-07-05/baby.pdf">baby.pdf</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Inside PropSheetPage</title>
      <link>https://docs.microsoft.com/archive/blogs/kenliu/inside-propsheetpage</link>
      <pubDate>Thu, 01 Nov 2007 03:59:00 GMT</pubDate>
      <dc:creator><![CDATA[TechNet Archive]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/kenliu/2007/11/01/inside-propsheetpage/</guid>
      <description><![CDATA[0:012&gt; dt comctl32!_PROPSHEETHEADERW&nbsp;&nbsp; +0x000...]]></description>
      <content:encoded><![CDATA[<p>0:012&gt; dt comctl32!_PROPSHEETHEADERW<br>&nbsp;&nbsp; +0x000 dwSize&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Uint4B<br>&nbsp;&nbsp; +0x004 dwFlags&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Uint4B<br>&nbsp;&nbsp; +0x008 hwndParent&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Ptr32 HWND__<br>&nbsp;&nbsp; +0x00c hInstance&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Ptr32 HINSTANCE__<br>&nbsp;&nbsp; +0x010 hIcon&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Ptr32 HICON__<br>&nbsp;&nbsp; +0x010 pszIcon&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Ptr32 Uint2B<br>&nbsp;&nbsp; +0x014 pszCaption&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Ptr32 Uint2B&nbsp; &lt;&lt;&lt;&lt;&lt; window title<br>&nbsp;&nbsp; +0x018 nPages&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Uint4B&nbsp; &lt;&lt;&lt;&lt;&lt; total pages<br>&nbsp;&nbsp; +0x01c nStartPage&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Uint4B<br>&nbsp;&nbsp; +0x01c pStartPage&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Ptr32 Uint2B<br>&nbsp;&nbsp; +0x020 ppsp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Ptr32 _PROPSHEETPAGEW<br>&nbsp;&nbsp; +0x020 phpage&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Ptr32 Ptr32 _PSP&nbsp; &lt;&lt;&lt;&lt;&lt; _PROPSHEETPAGEW array[nPages]<br>&nbsp;&nbsp; +0x024 pfnCallback&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Ptr32&nbsp;&nbsp; &nbsp;<br>&nbsp;&nbsp; +0x028 hbmWatermark&nbsp;&nbsp;&nbsp;&nbsp; : Ptr32 HBITMAP__<br>&nbsp;&nbsp; +0x028 pszbmWatermark&nbsp;&nbsp; : Ptr32 Uint2B<br>&nbsp;&nbsp; +0x02c hplWatermark&nbsp;&nbsp;&nbsp;&nbsp; : Ptr32 HPALETTE__<br>&nbsp;&nbsp; +0x030 hbmHeader&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Ptr32 HBITMAP__<br>&nbsp;&nbsp; +0x030 pszbmHeader&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Ptr32 Uint2B</p><p>&nbsp;* phpage is an array which contains nPages pieces of _PROPSHEETPAGEW</p><p>0:012&gt; dt comctl32!_PROPSHEETPAGEW<br>&nbsp;&nbsp; +0x000 dwSize&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Uint4B<br>&nbsp;&nbsp; +0x004 dwFlags&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Uint4B<br>&nbsp;&nbsp; +0x008 hInstance&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Ptr32 HINSTANCE__&nbsp;&nbsp; &lt;&lt;&lt;&lt;&lt; base address of module<br>&nbsp;&nbsp; +0x00c pszTemplate&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Ptr32 Uint2B&nbsp;&nbsp; &lt;&lt;&lt;&lt;&lt; resource Id<br>&nbsp;&nbsp; +0x00c pResource&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Ptr32 DLGTEMPLATE&nbsp;&nbsp; &lt;&lt;&lt;&lt;&lt; resource Id  - kernel32!FindResourceW<br>&nbsp;&nbsp; +0x010 hIcon&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Ptr32 HICON__<br>&nbsp;&nbsp; +0x010 pszIcon&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Ptr32 Uint2B<br>&nbsp;&nbsp; +0x014 pszTitle&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Ptr32 Uint2B<br>&nbsp;&nbsp; +0x018 pfnDlgProc&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Ptr32&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; +0x01c lParam&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Int4B<br>&nbsp;&nbsp; +0x020 pfnCallback&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Ptr32&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; +0x024 pcRefParent&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Ptr32 Uint4B<br>&nbsp;&nbsp; +0x028 pszHeaderTitle&nbsp;&nbsp; : Ptr32 Uint2B<br>&nbsp;&nbsp; +0x02c pszHeaderSubTitle : Ptr32 Uint2B<br>&nbsp;&nbsp; +0x030 hActCtx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Ptr32 Void<br></p><p>https://msdn2.microsoft.com/en-us/library/aa815151.aspx<br>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>Two years anniversary blog</title>
      <link>https://docs.microsoft.com/archive/blogs/kenliu/two-years-anniversary-blog</link>
      <pubDate>Wed, 31 Oct 2007 01:03:00 GMT</pubDate>
      <dc:creator><![CDATA[TechNet Archive]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/kenliu/2007/10/31/two-years-anniversary-blog/</guid>
      <description><![CDATA[Got one pair of important gifts. One is for me, another is for my wife.Thank you for giving me these...]]></description>
      <content:encoded><![CDATA[<p>Got one pair of important gifts. One is for me, another is for my wife.</p><p>Thank you for giving me these wonderful days darling.</p><p>Celebrate for two years from wedding in Zhengzhou, Celebrate for my 24th birthday, Celebrate for first time to know Tiffany, Celebrate for have a new target in the following years :)<br>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>Several methods and ideas for Heap leak detection</title>
      <link>https://docs.microsoft.com/archive/blogs/kenliu/several-methods-and-ideas-for-heap-leak-detection</link>
      <pubDate>Tue, 02 Oct 2007 06:42:00 GMT</pubDate>
      <dc:creator><![CDATA[TechNet Archive]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/kenliu/2007/10/02/several-methods-and-ideas-for-heap-leak-detection/</guid>
      <description><![CDATA[Heap and Handle allocation happens whilst calling malloc, new, sysallocatestring...If we forget to...]]></description>
      <content:encoded><![CDATA[<p>Heap and Handle allocation happens whilst calling malloc, new, sysallocatestring...</p><p>If we forget to release it by calling free, delete, sysfreestring, we experiences the memory leak.</p><p>There are several ways to avoid the leaking.</p><p>1. Use MS built-in detection API</p><p>#define _CRTDBG_MAP_ALLOC<br>#include &lt;crtdbg.h&gt; <br><br>_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF )</p><p>2. Mark the memory</p><p>#define HEAPLEAK(k) k = 0xCACF0000 + __LINE__ // CACF: check allocated check free + line number</p><p>3. Hook into the allocate and free functions</p><p>_CrtSetAllocHook(pfnHook)</p><p>hook to: calloc, malloc, realloc, free, memcpy, strcpy ...<br></p><p>4. Hook from the system level - what NuMega have done before...<br></p>]]></content:encoded>
    </item>
    <item>
      <title>Algorithm of finding the duplicated sub-strings in two strings</title>
      <link>https://docs.microsoft.com/archive/blogs/kenliu/algorithm-of-finding-the-duplicated-sub-strings-in-two-strings</link>
      <pubDate>Fri, 28 Sep 2007 11:51:00 GMT</pubDate>
      <dc:creator><![CDATA[TechNet Archive]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/kenliu/2007/09/28/algorithm-of-finding-the-duplicated-sub-strings-in-two-strings/</guid>
      <description><![CDATA[One tough issue, especially require the better performance and memory usage.However, I done it :)1....]]></description>
      <content:encoded><![CDATA[<p>One tough issue, especially require the better performance and memory usage.</p><p>However, I done it :)</p><p>1. It builds a table strlen(s1)*strlen(s2)<br>2. Compare the s1 and s2 and fill the equaled bit in the table<br>3. Find out the longest connected lines in that table<br>4. Re-build the string with the line's offset<br></p><p>Not sure if it is the best algorithm to do that :)</p><p>However it only spend 47ms to compare and find out the duplicate string ("pro") of "programming" and "professional" in 10000 times.</p><p>"abbazyabcyzabcegz" and ""xabcyzabcdegabbazyabh" for 10,000 times<br>Milliseconds: 109&nbsp;</p><p>Cool?&nbsp;</p><p>////// <br><br>StrNode* GetDupStr(__notnull LPCWSTR lpszP1, __notnull LPCWSTR lpszP2)<br>{<br>&nbsp;&nbsp; &nbsp;// 0. valid parameters, if SAL does not work<br>&nbsp;&nbsp; &nbsp;if (lpszP1==NULL || lpszP2==NULL || wcslen(lpszP1)==0 || wcslen(lpszP2)==0)<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;return NULL;<br>&nbsp;&nbsp; &nbsp;//<br>&nbsp;&nbsp; &nbsp;// 1. build the table<br>&nbsp;&nbsp; &nbsp;//<br>&nbsp;&nbsp; &nbsp;// calculate the size<br>&nbsp;&nbsp; &nbsp;int nLen1 = (int)wcslen(lpszP1);<br>&nbsp;&nbsp; &nbsp;int nLen2 = (int)wcslen(lpszP2);<br>&nbsp;&nbsp; &nbsp;int nMapLen = sizeof(bool)*nLen1*nLen2;<br>&nbsp;&nbsp; &nbsp;// allocate the memory @allocate abMap<br>&nbsp;&nbsp; &nbsp;bool* abMap;<br>&nbsp;&nbsp; &nbsp;abMap = (bool*)malloc(nMapLen);<br>&nbsp;&nbsp; &nbsp;//ZeroMemory<br>&nbsp;&nbsp; &nbsp;memset(abMap, 0x0, nMapLen);<br><br>&nbsp;&nbsp; &nbsp;//<br>&nbsp;&nbsp; &nbsp;// 2. compare and fill the table<br>&nbsp;&nbsp; &nbsp;//<br>&nbsp;&nbsp; &nbsp;for(int i=0; i&lt;nLen1; i++)<br>&nbsp;&nbsp; &nbsp;//rows<br>&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;WCHAR cRow = lpszP1[i];<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//check if there is duplicated char in previous chars, if so, memcpy directly<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;for(int k=0; k&lt;i; k++)<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (lpszP1[k]==cRow)<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;memcpy(&amp;abMap[i*nLen2], &amp;abMap[k*nLen2], nLen2);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;DEBUG("Dup: %c\n", cRow);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//loop cols<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;for(int j=0; j&lt;nLen2; j++)<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//cols<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//check equality<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (cRow==lpszP2[j])<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//MarkEqual(abMap, CalPos(nLen2, i, j));<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;MarkBit(abMap, CalcBitPos(nLen2, i, j));<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br>&nbsp;&nbsp; &nbsp;}<br><br>&nbsp;&nbsp; &nbsp;//<br>&nbsp;&nbsp; &nbsp;// 3. print out the table<br>&nbsp;&nbsp; &nbsp;//<br>#ifdef _DUPSTR_DEBUG_<br>&nbsp;&nbsp; &nbsp;PrintTable(abMap, lpszP1, lpszP2);<br>&nbsp;&nbsp; &nbsp;DEBUG("\n", NULL);<br>#endif<br><br>&nbsp;&nbsp; &nbsp;//<br>&nbsp;&nbsp; &nbsp;// 4. search table, find out the connected points<br>&nbsp;&nbsp; &nbsp;//<br>&nbsp;&nbsp; &nbsp;// get minimun strlen of two strings<br>&nbsp;&nbsp; &nbsp;int nMinLen = nLen1 &lt; nLen2 ? nLen1 : nLen2;<br>&nbsp;&nbsp; &nbsp;// build maxNode var @allocate pMaxNode<br>&nbsp;&nbsp; &nbsp;BNode *pMaxNode = NULL;<br>&nbsp;&nbsp; &nbsp;//<br>&nbsp;&nbsp; &nbsp;// loop the cols and rows from longest to shortest, and compare the maxlength with current nLen<br>&nbsp;&nbsp; &nbsp;// jump out if maxLen &gt; nLen<br>&nbsp;&nbsp; &nbsp;//<br>&nbsp;&nbsp; &nbsp;//loop for cols<br>&nbsp;&nbsp; &nbsp;for(int i=0; i&lt;nLen2; i++)<br>&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//current len<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;int nLen = nMinLen &lt; nLen2-i ? nMinLen : nLen2-i;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if ( pMaxNode==NULL || pMaxNode-&gt;len&lt;nLen)<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//get pNodes<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;BNode *pNode = CheckPoints(&amp;abMap[CalcBitPos(nLen2, 0, i)], nLen, nLen2+1);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//rebuild<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;RebuildMaxNodes(&amp;pMaxNode, &amp;pNode);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br>&nbsp;&nbsp; &nbsp;}<br>&nbsp;&nbsp; &nbsp;//then loop for rows<br>&nbsp;&nbsp; &nbsp;for(int i=1; i&lt;nLen1; i++)<br>&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;int nLen = nMinLen &lt; nLen1-i ? nMinLen : nLen1-i;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if ( pMaxNode==NULL || pMaxNode-&gt;len&lt;nLen)<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;BNode *pNode = CheckPoints(&amp;abMap[CalcBitPos(nLen2, i, 0)], nLen, nLen2+1);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;/* @refactor RebuildMaxNodes<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (pNode!=NULL)<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (pMaxNode==NULL)<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;DEBUG("leave null\n", NULL);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;pMaxNode = pNode;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;else if (pMaxNode-&gt;len &lt; pNode-&gt;len)<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;DEBUG("got new length: %d\n", pNode-&gt;len);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//free previous pMaxNode<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;ReleaseNode(pMaxNode);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;pMaxNode = pNode;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;else if (pMaxNode-&gt;len == pNode-&gt;len)<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;DEBUG("get duplicated\n", NULL);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;pMaxNode-&gt;next = pNode;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;else<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;ReleaseNode(pNode);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;*/<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;RebuildMaxNodes(&amp;pMaxNode, &amp;pNode);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br>&nbsp;&nbsp; &nbsp;}<br><br>&nbsp;&nbsp; &nbsp;//<br>&nbsp;&nbsp; &nbsp;// 5. print out pMaxNodes<br>&nbsp;&nbsp; &nbsp;//<br>&nbsp;&nbsp; &nbsp;StrNode* pstrNode = NULL;<br>&nbsp;&nbsp; &nbsp;//<br>&nbsp;&nbsp; &nbsp;BNode* pn = pMaxNode;<br>&nbsp;&nbsp; &nbsp;//foreach pMaxNode<br>&nbsp;&nbsp; &nbsp;while(pn!=NULL)<br>&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//calculate the string offset<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;int nStrOffset = (int)((pn-&gt;pbStart - abMap) % nLen2);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//allocate new string @allocate lpszOutput<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;LPWSTR lpszOutput = new WCHAR[pn-&gt;len+1];<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;memset(lpszOutput, 0x0, (pn-&gt;len+1)*sizeof(WCHAR));<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;memcpy(lpszOutput, lpszP2+nStrOffset, pn-&gt;len * sizeof(WCHAR));<br><br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;DEBUG("%x =&gt; ", pn-&gt;pbStart);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;DEBUG("%d =&gt; ", pn-&gt;len);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;DEBUG("%s\n", lpszOutput);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//DEBUG("%x =&gt; %d =&gt; %s\n", pn-&gt;pbStart, pn-&gt;len, lpszOutput);<br><br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//attach string to return structure<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (pstrNode==NULL)<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//build the node<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;pstrNode = BuildStrNode(lpszP2+nStrOffset, pn-&gt;len, lpszOutput);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;HEAPLEAK(pstrNode-&gt;magic, 0xCACF0169); <br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;else<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//build the node<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;/* @refactor BuildStrNode<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;StrNode* psn = new StrNode;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;memset(psn, 0x0, sizeof(StrNode));<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;psn-&gt;lpSrc = lpszP2+nStrOffset;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;psn-&gt;len = pn-&gt;len;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;psn-&gt;str = lpszOutput;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;psn-&gt;next = NULL;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;pstrNode-&gt;next = psn;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;*/<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;StrNode* psn = pstrNode;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;while(psn-&gt;next!=NULL)<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;psn = psn-&gt;next;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;psn-&gt;next = BuildStrNode(lpszP2+nStrOffset, pn-&gt;len, lpszOutput);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;HEAPLEAK(psn-&gt;next-&gt;magic, 0xCACF0189);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br><br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;pn = pn-&gt;next;<br>&nbsp;&nbsp; &nbsp;}<br>&nbsp;&nbsp; &nbsp;//@release pMaxNode<br>&nbsp;&nbsp; &nbsp;ReleaseBNode(pMaxNode);<br>&nbsp;&nbsp; &nbsp;//@release abMap<br>&nbsp;&nbsp; &nbsp;delete abMap;<br><br>&nbsp;&nbsp; &nbsp;return pstrNode;<br>}</p><p>Attached full code files.<br>&nbsp;</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/telligent.evolution.components.attachments/01/5892/00/00/02/06/83/55/MaxDuplicatedString.7z" original-url="https://blogs.technet.com/cfs-filesystemfile.ashx/__key/telligent-evolution-components-attachments/01-5892-00-00-02-06-83-55/MaxDuplicatedString.7z">MaxDuplicatedString.7z</a></p>]]></content:encoded>
    </item>
    <item>
      <title>J2EE and ASP.NET</title>
      <link>https://docs.microsoft.com/archive/blogs/kenliu/j2ee-and-asp-net</link>
      <pubDate>Wed, 26 Sep 2007 20:18:00 GMT</pubDate>
      <dc:creator><![CDATA[TechNet Archive]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/kenliu/2007/09/26/j2ee-and-asp-net/</guid>
      <description><![CDATA[Many Java developer begins to learn C#. Then they found there are lots of similar concepts and...]]></description>
      <content:encoded><![CDATA[<p>Many Java developer begins to learn C#. Then they found there are lots of similar concepts and frameworks in ASP.NET</p><p>1. ASPX vs JSP<br>2. Code Behind C# vs Servlet<br>3. Web Controls vs TagLib<br>4. Master/Content Page vs Tiles<br>5. Validation vs Validation in Java<br>6. ViewState vs FormBean<br> 7. ASP.NET vs Struts<br>
</p><p>I was frustrated why my company published this Struts-like framework at the very beginning, but after a while, I know the reason:</p><p>1. ASP is too old and may worse than PHP<br>2. ASP.NET intend to bring a new easy-to-use platform to developer and reduce the coding tasks for developers. That's the major target of this framework.<br>3. ASP.NET is a framework, such as Struts, Spring, Velocity, but not a platform, C# is the platform</p><p>So, we should compare the C# enterprise platform and J2EE platform, make sense?</p><p>Will do that later.<br></p>]]></content:encoded>
    </item>
    <item>
      <title>Code and Design - Part 2 - TDD</title>
      <link>https://docs.microsoft.com/archive/blogs/kenliu/code-and-design-part-2-tdd</link>
      <pubDate>Wed, 26 Sep 2007 19:58:00 GMT</pubDate>
      <dc:creator><![CDATA[TechNet Archive]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/kenliu/2007/09/26/code-and-design-part-2-tdd/</guid>
      <description><![CDATA[TDD - Test Driven DevelopmentWhy TDD? First we need to know why Unit Test.Unit Test intend to bring...]]></description>
      <content:encoded><![CDATA[<p>TDD - Test Driven Development</p><p>Why TDD? First we need to know why Unit Test.</p><p>Unit Test intend to bring us a assumption and we need and only need to implement all the functionalities which defined in the Test. And the test will cover all kinds of possible calls from outside caller. The Test treats the function as a black-box and just make the guess to call it.</p><p>It is a very good and accurate technology to test the robust of the code and reduce the bug. But we are human being, once we developed the function, it is more easier for us to write the "Success assumption" Test instead of "Failure assumption" one.</p><p>TDD is the best practice to force us develop the functions from perspective of Tester and function caller. It will prevent to develop the functions that never ever will be called. Also it could avoid to waste our time to develop the never been called functions and codes.</p><p>Recommend book: Test Driven Development - Example - Kent Beck.</p><p>Here is the best example from that book to explain what is TDD:</p><p>1. Write the Test</p><p>AssertEquals( functionName(1,2), 3);</p><p>2. Develop the function</p><p>function functionName(int a, int b)<br>{<br>return a + b;<br>}</p><p>3. Enhance the Test</p><p>AssertEquals( functionName(-1, -2), 3);</p><p>4. Enhance the function</p><p>function functionName(int a, int b)<br>
{<br>
return Math.abs(a + b);<br>
}</p><p>5. Repeat steps 3,4 until all the features of this function satisfied you :)</p><p>&nbsp;</p><p>Best Practice<br>=================================<br>1. Write the Test, then write the code<br>2. Assume Fails, not success - the way of thinking<br>3. Code should satisfy your Unit Test, not yourself<br>4. Do not forget good code standard and comments, XP is extreme programming, term extreme forces on the methodology, programming forces on the standards<br>5. Do not conflict with the Design, if something wrong, review your design and think about that<br>6. Pay attention to your Test code, refactor it if necessary.<br>7. Refactor the code after all functions have been implemented<br><br>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>Code and Design - Part 1 - the framework</title>
      <link>https://docs.microsoft.com/archive/blogs/kenliu/code-and-design-part-1-the-framework</link>
      <pubDate>Wed, 26 Sep 2007 19:51:00 GMT</pubDate>
      <dc:creator><![CDATA[TechNet Archive]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/kenliu/2007/09/26/code-and-design-part-1-the-framework/</guid>
      <description><![CDATA[There are too many programming methodologies, but how to use it?I am thinking of the general...]]></description>
      <content:encoded><![CDATA[<p>There are too many programming methodologies, but how to use it?</p><p>I am thinking of the general framework of the period of my software development. Here is my conclusion:</p><p>1. Software Design - UML - To design the class and functions<br>2. Design Inspection - Team Review<br>3. Unit Test - TDD<br>4. Implement the functionality - Pairs programming if possible<br>5. Go back 3, until FULL green<br>6. Code Inspection - Peer Review, Team Review<br></p><p>I will try to find some best practices and summarize it of each phrase.&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>Control SysTreeView and SysListView in another window/process</title>
      <link>https://docs.microsoft.com/archive/blogs/kenliu/control-systreeview-and-syslistview-in-another-windowprocess</link>
      <pubDate>Thu, 20 Sep 2007 00:16:00 GMT</pubDate>
      <dc:creator><![CDATA[TechNet Archive]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/kenliu/2007/09/20/control-systreeview-and-syslistview-in-another-windowprocess/</guid>
      <description><![CDATA[Last year I developed one tool to control the SysTreeView and SysListView in Clarify (one internal...]]></description>
      <content:encoded><![CDATA[<p>Last year I developed one tool to control the SysTreeView and SysListView in Clarify (one internal tool). Here I'd like to share a part of sour code.</p><p>How to enumerate the windows<br>===============================<br>&nbsp;&nbsp;&nbsp; HWND hClarifyWnd;<br>&nbsp;&nbsp;&nbsp; EnumWindows(<span style="font-weight: bold;">EnumClarifyProc</span>, (LPARAM)&amp;<span style="font-weight: bold;">hClarifyWnd</span>);<br><br>BOOL CALLBACK <span style="font-weight: bold;">EnumClarifyProc</span>(HWND <span style="font-weight: bold;">hWnd</span>, LPARAM lParam)<br>{<br>&nbsp;&nbsp;&nbsp; if( IsWindowVisible(hWnd) ) {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; HWND* phCwnd = (HWND*)lParam;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int nLen = GetWindowTextLength(hWnd);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; LPSTR lpszTitle = new CHAR[nLen + 1];<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">GetWindowText</span>(hWnd, lpszTitle, nLen+1);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(strstr(lpszTitle, CLARIFY_TITLE)){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //assign window handle<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; *phCwnd = hWnd;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; delete lpszTitle;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return TRUE;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; delete lpszTitle;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; return TRUE;<br>}<br></p><p>How to control the controls in another window/process<br>====================================<br>bool SendMessageWrapper(HWND hWnd, HANDLE hProcess, HTREEITEM hItem, int TVM_FLAG, TV_ITEM *tvItemParam, char* item)<br>{<br>&nbsp;&nbsp;&nbsp; TV_ITEM tvItm,*tvItem;<br>&nbsp;&nbsp;&nbsp; if (tvItemParam!=NULL)<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tvItem = tvItemParam;<br>&nbsp;&nbsp;&nbsp; else<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tvItem = &amp;tvItm;<br><br>&nbsp;&nbsp;&nbsp; TV_ITEM *ptvItem;<br>&nbsp;&nbsp;&nbsp; ptvItem = (TV_ITEM*) <span style="font-weight: bold;">VirtualAllocEx</span>(hProcess, NULL, sizeof(TV_ITEM), MEM_COMMIT, PAGE_READWRITE);<br><br>&nbsp;&nbsp;&nbsp; char *pItem;<br>&nbsp;&nbsp;&nbsp; pItem = (char*) <span style="font-weight: bold;">VirtualAllocEx</span>(hProcess, NULL, MAX_CHAR_LEN, MEM_COMMIT, PAGE_READWRITE);<br><br>&nbsp;&nbsp;&nbsp; if (ptvItem==NULL || pItem==NULL)<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return false;<br><br>&nbsp;&nbsp;&nbsp; (*tvItem).hItem = hItem;<br>&nbsp;&nbsp;&nbsp; (*tvItem).mask = TVIF_TEXT | TVIF_CHILDREN;<br>&nbsp;&nbsp;&nbsp; (*tvItem).pszText = pItem;<br>&nbsp;&nbsp;&nbsp; (*tvItem).cchTextMax = MAX_CHAR_LEN;<br><br>&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">WriteProcessMemory</span>(hProcess, ptvItem, tvItem, sizeof(TVITEMEX), NULL);<br><br>&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">SendMessage</span>(hWnd, TVM_FLAG, 0, (LPARAM)ptvItem);<br><br>&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">ReadProcessMemory</span>(hProcess, pItem, item, MAX_CHAR_LEN, NULL);<br>&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">ReadProcessMemory</span>(hProcess, ptvItem, tvItem, sizeof(TVITEMEX), NULL);<br><br>&nbsp;&nbsp;&nbsp; // free<br>&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">VirtualFreeEx</span>(hProcess, ptvItem, 0, MEM_RELEASE);<br>&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">VirtualFreeEx</span>(hProcess, pItem, 0, MEM_RELEASE);<br><br>&nbsp;&nbsp;&nbsp; return true;<br>}<br>&nbsp;</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/telligent.evolution.components.attachments/01/5892/00/00/01/99/90/29/ClarifyHelperMsg.cpp" original-url="https://blogs.technet.com/cfs-filesystemfile.ashx/__key/telligent-evolution-components-attachments/01-5892-00-00-01-99-90-29/ClarifyHelperMsg.cpp">ClarifyHelperMsg.cpp</a></p>]]></content:encoded>
    </item>
    <item>
      <title>web-app frameworks</title>
      <link>https://docs.microsoft.com/archive/blogs/kenliu/web-app-frameworks</link>
      <pubDate>Wed, 19 Sep 2007 09:57:00 GMT</pubDate>
      <dc:creator><![CDATA[TechNet Archive]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/kenliu/2007/09/19/web-app-frameworks/</guid>
      <description><![CDATA[J2EE: The platform I deeply loved!ASP.NET: More and more powerful.AJAX + server-side app: I will...]]></description>
      <content:encoded><![CDATA[<p>J2EE: The platform I deeply loved!<br>ASP.NET: More and more powerful.<br>AJAX + server-side app: I will focus on in the future.<br>PHP, mod_perl ...: will fade out of the history</p><p>&lt;&gt;&lt;&gt;&lt;&gt;</p><p><b>J2EE</b>: very complex platform, you can do anything you want to do on this platform, it contains so many great ideas and concept, and the performance is quite amazing in the server side. but lots of people have the misunderstanding and intend to use other platforms... it is not very popular even though it should be.<br>====================================<br>JSP: one good way to separate the Page and Logical, and it will be converted to Servlet (java code) at the runtime. Good concept. (asp)<br>TagLib: great thing, it is a way to separate the Page and Logical in JSP. (asp.net/web controls)<br>Servlet: Historic things. Good controller. provided Filter mechanism, it is a extreme good concept and it influences all the web-app frameworks.<br>JDO: Very cool concept, and with several nice implementation, such as Kodo JDO, OpenAccess JDO, Apache JDO...<br>Hibernate: good concept and implementation which was inherited from JDO but become more and more stronger and popular in Open Source community recently.<br>EJB2: Good concept but too complicated implementation and bad performance.<br>EJB3: Steal several good points from JDO, good implementation.<br>... others ...<br></p><p>Although I am not a J2EE specialist as I work for Microsoft, but I really love this tech :)<br></p><p><br><b>ASP.NET</b>: good platform, but sometimes it does not do the simple things in the simple way, and there is just few good practice in the Internet and lots of newbies use this tech, so... the live ASP.NET applications always contain strange issues. low performance, not security... actually it is not the truth.<br>====================================<br>Page Events: good concept, but a little bit complex... maybe MS intend to migrate the win32 developer to .net platform and web-based app environment more smoothly, but it is really different as the win32 platform, the network latency and server performance is the big problem of ASP.NET applications if there are too many Page Events.<br>View State: good idea to generate and maintain it automatically. Actually it could be saved in server-side :)<br>Lots of web controls: good implementation, concept is inherited from J2EE Taglib.<br>ADO.NET: old wine in new bottle.<br>Data Binding: Good concept and inherits from win32 age.<br></p><p>It is a easy to use platform for developer.&nbsp;</p><p>&nbsp;<br><b>AJAX + Server-side App</b>: GWT from Google, YUI from Yahoo, they all intend to build a big client-side AJAX platform to reduce the dependency of server and client platform. That is a good idea and right way, but it will effect to all the platform provider... so, from the marketing perspective, not sure how many developers will follow this alliance.<br>=====================================<br>JavaScript to build the rich client:<br>Web Service (SOAP call) or JSON call for communication:<br>Server-side application:</p><p>it is a good idea but need the good framework to support it.</p><p>&nbsp;<br>PHP &amp; Mod_Perl: my lovely Perl, my cute PHP, time is fast... who knows what will happen to them...<br><br></p>]]></content:encoded>
    </item>
  </channel>
</rss>