<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    如鵬網 大學生計算機學習社區

    CowNew開源團隊

    http://www.cownew.com 郵件請聯系 about521 at 163.com

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      363 隨筆 :: 2 文章 :: 808 評論 :: 0 Trackbacks

    #

      這篇文章昨天怎么也貼不上去,今天貼一貼試試。今天的blog鍛煉回來再寫。
      今天早上起來不知怎么的感覺特別累。來深圳三個多月依來這是第一次感覺這么累,可能和這兩天連續奮戰有關系吧。忙過了這陣子要稍微修整一下了,否則身體垮了就太不值得了。不知道是產品延期發版了兄弟們有點放松警惕了,還是前兩天市場部一個同事去世對同事們敲響了警鐘了,大家下了班都早早的回家了。只有少數幾個人仍在堅守崗位,我當然就是其中一個了。給現場支持的同事寫了一個使用幫助文檔,然后我就琢磨起DB2來。來這個公司最大的好處就是可以接觸很多高級的東西,呵呵。
      不管你說DB2強大也好,穩定也好,但從一個開發者的角度來講總感覺用著不舒服。比如它竟然不支持修改一個字段的類型,一旦你字段類型定義錯了,那么就必須刪掉重來,很恐怖呀。還有它的錯誤提示信息也很讓人摸不到頭腦,執行insert語句的時候如果某個字段不允許為空,它就提示你一個什么tableid=**,colId=**之類的,然后再告訴你怎么根據tableid=**,colId=**去查到底是哪個字段不允許為空。真是奇怪了,你幫我查出來,然后顯示給我不好嗎?在這一點上還是感覺微軟的東西好用呀。所以在mssql上開發,然后到DB2上部署也是個不錯的選擇。各取所長呀。
      今天看了看HTC,也做了一個簡單的例子。一開始怎么也無法運行,后來發現在PUBLIC:與ATTACH之間不能有空格,否則就無法出現預期的效果。又看了看網上對htc的評論并不是很好,主要就是集中在資源消耗、穩定性和微軟以后將不再支持方面。特別是溫少的評論更有權威呀,他是見證了EAS.NET成敗的一個人,對HTC的優劣認識更深。抽時間和他聊聊,好在是一個Company的,只是不知道人家高手會不會有時間陪咱聊呀。呵呵。
      太陽走了,留下的是星光;
      云朵走了,留下的是藍天;
      微笑走了,留下的是陰霾;
      你走了,留下的是回憶。
      風吹走了你,風吹干了淚,
      留下的是干枯的雙眼。

    posted @ 2005-10-27 21:04 CowNew開源團隊 閱讀(740) | 評論 (3)編輯 收藏

      繼續數據導入中,呵呵,不過終于看到曙光了,是騾子是馬周四提到客戶現場就知道了。今天晚上又忙了一陣子,J2EE打包部署很是麻煩呀,害的我叫得快餐都涼了才囫圇吞棗的吃了兩口。
      回到宿舍同宿舍的兄弟想通過網絡鄰居訪問我的電腦,但是就是訪問不了,于是乎上網查了一下網絡鄰居的原理。這一查不要緊呀,太搞笑了,微軟的網絡鄰居實現的這么“民主”呀,竟然是誰先進來、誰更高級就推舉誰當主瀏覽器,竟然還要選出一個“副手”做為備份,呵呵。不過不知道為什么微軟當初這樣設計,很容易就出現網上鄰居不可用呀,不過好在大部分人用網絡鄰居用的不是很多。
      這兩天對web的Rich client開發一直很感興趣,翻了翻公司控件開發部的服務器,人家做的確實不錯,用htc做的web前端太漂亮了,看來我要花一段時間研究研究htc了,雖然說htc是依賴IE6的,但是在企業級web開發中這也不是什么問題,我可不是那種敵視微軟的pure***的程序員。只要能快速完美的滿足客戶各種“變態”的需求,我就認為它是好的技術。 
      下載了一些htc的教程和一些示例代碼,我也不打算深入學習,畢竟我還是想多在java企業級開發上邊下功夫,但是多接觸點東西還是好的。在這行混的一個準則是你不必對什么都精通,但是必須什么都了解一點,其實業界更缺少的是這種“蜻蜓點水的專才”。話題扯遠了,還是說說HTC吧。HTC確實是web界面開發的一種進步,但是我感覺進步還不是很快,呵呵。如果能象Delphi或者.net那樣具有完全行為和屬性的組件體系的話就更完美了,程序員只要在htm中輸入類似于下面的代碼就可以將控件引入。<MyComponent/>。聽說微軟正在將HTC做為web標準提向w3c,希望能得到批準,并且做的更完美,那樣就能大大節省我們的開發時間了。
      好了,不早了,我要休息了,這兩天我看看htc的教程和代碼,我會及時與大家交流自己的心得體會的。
    posted @ 2005-10-26 00:55 CowNew開源團隊 閱讀(1155) | 評論 (2)編輯 收藏

    ? 數據導入功能終于做的差不多了,服務器端導入模式也試了一下,臨下班之前還有nullpointerexception錯誤沒有解決,還有就是生成憑證有問題。總感覺項目中有太多將就的東西了,底層開發框架設計的很好,擴展性也很強。但是業務框架就差很多了,那個憑證生成平臺竟然建立在源單據要建立一個名字為fivouchered字段的基礎之上,否則根本跑不起來,耦合性太強了,而且這種耦合是很不容易被發現的。周四就要把做的這個Demo發到客戶現場了,希望一切都平安,否則下周甚至下下……下周都不可能安心進入項目開發了。今天項目組開例會沒有前一陣子那么忙碌了,產品延期發版了兩個多月,戰友們也感覺壓力小了許多。但是風險是無處不在的,只希望需求、開發、測試合作更緊密一點,交流更通暢一些,多快好省的讓產品發版,少點全員加班。
    ? 忙是忙,總不能把自己困死在工作上的。畢竟還是要自己學點東西的。本想回來看一看hibernate的源代碼的,但是同宿舍兄弟剛買了臺電腦要用我的電腦做代理上網。生平第一次看到用雙網卡實現共享上網,又學了一招,我那個兄弟可是個網絡高手,以后要經常向他學習了,等有時間買個小路由,讓他教教我怎么配置路由器。
    ? 時間不多只能把我前一陣子研究的java中調用腳本語言的東西拿出來整理一下了。java中調用腳本語言有很廣泛的用途,比如用戶自定義公式,自定義單據轉換規則,用戶自定義工作流等等。java中調用腳本語言有很多中實現,比如Jython、Groovy、Beanshell等等。但是即使對于有一定開發經驗的程序員學習它們是需要一段時間的。而提起腳本,無論是程序員還是有一定軟件開發基礎的客戶(例如客戶公司的網管、信息管理員等等)都會想起javascript和VBScript,如果我們的系統使用這些用戶熟悉的腳本語言,必將降低系統學習的難度。VBScript是捆綁在windows平臺下的,因此javascript就成了我們專注的對象。javascript引擎可以在NetScape的js.jar中找到,而現在這個包已經做為一個開源項目獨立出來了,項目的名字是Rhino,項目網站:http://www.mozilla.org/rhino/。
    ? Rhino支持javascript標準的所有特性,如賦值、運算、判斷語句、循環語句、甚至簡單的io操作。Rhino很簡單易用,我以一個例子來說明,這個例子就是允許用戶設定一個使用x,y兩個變量進行一定邏輯算術運算(運算規則用戶用javascript定義),并允許用戶對x,y賦值,然后運行得出計算結果。代碼如下:
    ??????? Context ctx = Context.enter();
    ??????? Scriptable scope = ctx.initStandardObjects();
    ???????
    ??????? scope.put("x", new Integer(20));
    ??????? scope.put("y", new Integer(30));
    ??????? try
    ??????? {
    ????????? ctx.evaluateString("if(x",1,null);
    ????????? System.out.println(scope.get("result", scope));
    ??????? }
    ??????? finally
    ??????? {
    ??????????? Context.exit();
    ??????? }
    很簡捷吧。scope.put("x", new Integer(20))的意思是為變量x賦值,ctx.evaluateString("if(x",1,null); 則是運行javascript腳本,而scope.get("result", scope)則是得到運算結束后變量的值,我們采用result做為返回值,所以scope.get("result", scope)就表示得到返回值。不錯吧。嘿嘿,很方便呀。
    ? 好了,都凌晨一點鐘了,該睡覺了,明天還要改bug呢,爭取提前把任務搞定,周五調休。
    posted @ 2005-10-25 22:58 CowNew開源團隊 閱讀(4741) | 評論 (5)編輯 收藏

      今天又搞了一天的數據導入程序,本以為今天會比較輕松,沒想到有忙忙乎乎了一天。中午晚上都是叫得外賣(野生菌肉片飯,TNND香死了,嘻嘻!),而且都是用10分鐘搞定入肚。不過感覺鮮粉人家的飯就是比桃源村那個布拉粉腸王的好吃,更別提冶金大廈下邊那個嘉惠餐廳了,要不是俺口袋里銀子不多,我才不去那個垃圾餐廳呢。不過更羨慕那些從家里帶飯來的XDJM呀,有家的感覺真好,連飯都是熱的,不像俺們,在盤子里是熱的,吃到嘴里是涼的,進到肚子里是冰的,冰得人心痛。
      東軟那幫人真垃圾,讓他們提供個數據接口他們都故意為難你,讓你得程序繞了八百個彎才把數據導進去,而且還有很小的精度誤差。東軟我真服了了你了,你怎么也算是國內有影響的大公司了吧,怎么這樣的胸懷都沒有呀,劉雞人呀,I 他媽 服了 You!
      抽空給在濟南兼職的時候那個項目經理打了個電話。年紀大了就是羅嗦了呀,今天又跟我說他在深圳的幾個同學都沒有結婚之類的話,言語中有一點不理解又有一些羨慕。想想也是呀,他都是一個7歲小丫頭的爸爸了,而比他大的同學還在耍單,肯定羨慕死他呀。至于他們為什么還在耍單,他也沒說。不過我聽說過一句話,來深圳的女人分為三種:當過雞的,正在當雞的,將要當雞的。應該還有下文吧,來深圳的男人分為三種:被傷害過的,正在被傷害的,將要被傷害的。被傷害的男人為了忘掉過去,為了自強,一堵氣來深圳創自己的一片天下;正在被傷害人帶著意思遺憾來深圳療傷;而來了深圳的幸福男人總會有一天嘗到來這的苦果,從此弄的遍體鱗傷,封閉自己的內心,從此落寞。
    posted @ 2005-10-24 00:52 CowNew開源團隊 閱讀(520) | 評論 (4)編輯 收藏

    ??? 暈死,今天加了一天的班,還沒有搞定,明天還要加班呀,不過還好,明天不用那么累了。工作再怎么累也不能讓身體垮掉呀,再說那花了我七百塊大洋的健身卡也不能浪費。進了健身房,沖前臺的小MM拋了無限神情的媚眼以后就開始跑跑跳跳,上上下下,彎彎挺挺的,各種姿勢的,每天不同而又相同的運動中了。今天精神不是太好,舉重舉到第30個就“不舉”了。才跑了10分鐘小跑已經大汗淋漓,索性不跑了。走出健身房的時候,前臺小MM那句柔情萬千的“bye bye”把我弄得渾身麻酥酥的,不過想想人家對會員都這樣,你自作多情干什么,靠,犯賤!周末社區里的人不多,不過還是能看見或一對、或一家的在社區那散步。在深圳這個找不到家的感覺的地方,時常的在這個社區里散散步也許還能找回自己活著的感覺。可是那個“家的感覺”是人家的,你的“家”不照樣是那個月租380的小房間嗎?再次犯賤!
    ? 回到宿舍把電腦打開,《大話西游》終于下完了,看來電信還沒有完全屏蔽BT呀。你說我幼稚也好,說我低俗也好,說我落伍也好,但是《大話西游》我是百看不厭。也許我就是那個孫悟空轉世吧,只是也許輪回太多了,當初的猴崽子已經變成了一只小胖娃娃。但是不變的是命運的安排。也許你曾自由飛翔、也許你是山賊、也許和紫霞轟轟烈烈、也許對晶晶眉來眼去,但命中注定你要被烙上那三棵痔,注定要被套上緊箍咒。曾經的愛你一萬年的海誓山盟,曾經在你心中留下眼淚的女人,曾經幫你踩滅大火的兄弟,這些都將離你而遠去。不要再回憶,不管它曾多么美好,命中注定前行才是你的方向。為你而被殺死的那些兄弟們是否已經投胎,被師傅折磨而自盡的兩個小妖是否已經變回原型,盤絲洞是否會有新的主人,在城堡上擁抱的他們是否會幸福永遠,這些都不用你再管,不用你再操心,他們都象你一樣在命運定律的安排下有序的運轉著。你需要的只是抹去紫霞在你唇邊留下的香味,背起鐵棒,象一條黃狗一樣離開曾經的全部,然后扔掉香蕉皮,向命中注定的地方前行。
    posted @ 2005-10-23 01:00 CowNew開源團隊 閱讀(352) | 評論 (0)編輯 收藏

       類似于Delphi的窗體設計器界面,用戶可以自由拖放控件,并可以編輯控件的屬性,支持Delphi的屬性編輯器的概念。此阿用了反射機制和插件技術,使得增加新的控件非常容易。并可以把設計的窗體保存到文件中,還可以生成exe文件。由于采用的是xml格式保存,并且設計的時候充分考慮了可移植性,因此本程序可以很容易的用其他語言實現,而且生成的窗體文件可以以windows界面或者web界面展示。可以把此程序作為開發工作流引擎或二次開發平臺的基礎。我會繼續開發,開發過程中的經驗也將及時與大家分享。
    fdesinger1.jpg
    posted @ 2005-10-22 01:03 CowNew開源團隊 閱讀(1317) | 評論 (6)編輯 收藏

     

      近日(呵呵,這篇文章是去年寫的)用了兩個月開發了一個物流信息系統,這個系統是兩層、三層相結合,C/SB/S相結合的系統。雖然限于時間的緊張和人手的原因,系統規模不是很大,但是其中涉及的技術卻很全面。在這個《開發技術篇》中我們將講解我在開發系統中遇到的技術問題及解決方案,希望對大家有幫助。對于物流信息系統的分析設計問題,我將在另一篇文章《物流信息系統開發手記――系統構架篇》中講解。

     

    一、Midas的安全問題。

        Midas技術是Delphi中進行三層開發的首選技術,它不僅有純DCOM/COM+(COM+技術是.NET技術的基礎)的優點,而且也結合了Delphi的快速開發特性,可以快速開發出想要的系統,其開發速度是用VC,PB等開發DCOM的數十倍,把程序員從煩雜的代碼中解脫出來,從而將更多的精力投入到業務邏輯的設計中去。

        但是Midas技術的一個最令人擔憂的就是它的安全問題:

    遠端只要知道應用服務器的端口號即可訪問到應用服務器,而一旦訪問到應用服務器,TClientDataSet即可獲得ProviderNames列表。一旦知道了ProviderNames列表,這就相當于將數據庫暴露在外了。

    關于可輕易獲得ProviderNames列表的問題,我使用下面的方法解決:

     在服務器端定義一個

    LoginMTS(const AUserId, APassword: WideString): WordBool;

    方法。初始狀態下,所有的DataSetProvider和數據集的連接斷開。用戶必須調用LoginMTS并傳遞用戶名和密碼,登陸成功才將DataSetProvider和數據集的連接打開。這樣如果用戶驗證沒有通過,即使它獲得了ProviderNames列表也沒法調用接口中的方法對數據庫進行操作。

    二、Midas中主從表的實現

    主從表的應用在信息系統中應用很廣。在兩層開發中我們可以通過直接建立兩個數據集之間為主從關系來實現主從表;在三層中雖然我們仍然可以通過直接建立兩個數據集之間為主從關系來實現主從表,但是這樣就要求把數據庫中所有相關的數據行都下載到本地,喪失了三層開發的優勢。我在實際中使用下面的方法實現。這里我以實現入庫單查詢、添加、修改、刪除(CRUD)為例來講解:

    1)新建一個MTS Data Module,命名為TmtsStockInListBiz,增加如下方法:

        function QueryStockInListMasterById(const AId: WideString;

          var ADatas: OleVariant): WordBool; safecall;

        function QueryStockInListSlaveByMasterId(const AId: WideString;

          var ADatas: OleVariant): WordBool; safecall;

        procedure UpdataStockInListMaster(var ADatas: OleVariant); safecall;

        procedure UpdataStockInListSlave(var ADatas: OleVariant); safecall;

        function GenerateStockInListId: WideString; safecall;

     

    QueryStockInListMasterById作用是根據入庫單單號查詢入庫單的基本信息(入庫日期、負責人等),Aid為入庫單單號,Adatas為返回值,其格式就是Midas的數據包,可以將其附給ClientDatSetData屬性。

    QueryStockInListSlaveByMasterId作用是根據入庫單單號查詢入庫單的詳細信息(商品條碼,數量)

    UpdataStockInListMaster是對入庫單主表進行刪除、添加、修改操作。只要將ClientDataSetDelta屬性做為傳遞即可。

    UpdataStockInListSlave是對入庫單從表進行刪除、添加、修改操作。

    GenerateStockInListId是產生一個唯一的入庫單號。

    下面是幾個方法的代碼,都很簡單,就不多解釋了,可以查看Delphi的幫助。

    function TmtsStockInListBiz.QueryStockInListMasterById(

      const AId: WideString; var ADatas: OleVariant): WordBool;

    begin

      result := false;

      ADatas := null;

      try

        cdsQuery.Close;

        cdsQuery.CommandText := 'select * from t_StockInListMaster where Id=:Id';

        cdsQuery.Params.ParamByName('Id').AsString := AId;

        cdsQuery.Open;

        if cdsQuery.RecordCount > 0 then

        begin

          result := true;

          ADatas := cdsQuery.Data;

        end;

      finally

        cdsQuery.Close;

      end;

    end;

     

    procedure TmtsStockInListBiz.UpdataStockInListMaster(

      var ADatas: OleVariant);

    var

      eCount: Integer;

      OwnerData: OleVariant;

    begin

      DCOMConStockInList.GetServer.AS_ApplyUpdates('dspStockInListMaster',

        ADatas, -1, eCount, OwnerData);

    end;

     

    function TmtsStockInListBiz.GenerateStockInListId: WideString;

    var

      LPrior: string;

      i: Integer;

    begin

      cdsQuery.Close;

      cdsQuery.CommandText := 'select top 1 id from t_StockInListMaster order by id desc';

      cdsQuery.Open;

      LPrior := cdsQuery.FieldByName('Id').AsString;

      i := StrToIntDef(RightStr(LPrior,8),0);

      Inc(i);

      result := 'RK' + FormatFloat('00000000',i);

      cdsQuery.Close;

    end;

     

    2)、新建一個應用程序,通過DCOMConnectionSocketConnection等連接到MTS組件,然后就可以調用MTS的相應的方法實現客戶端功能了。

    放入cdsStockInListMastercdsStockInListSlave兩個ClientDataSet控件,在控件上點擊右鍵,選擇“FieldsEditor”新建于服務器中的字段同樣的字段,然后再次在控件上單擊右鍵,選擇“CreateDataSet”,建立一個本地數據庫。

    3

    根據入庫單號查詢入庫單的方法實現:

    procedure TFormStockInList.BtnFindClick(Sender: TObject);

    var

      v,vs: OleVariant;

    begin

      if SocketConStockInList.AppServer.QueryStockInListMasterById(Trim(LEdtId.Text), v) then

      begin

        cdsStockInListMaster.Data := v;//顯示入庫單主表(主要信息)

     

        if SocketConStockInList.AppServer.QueryStockInListSlaveByMasterId(Trim(LEdtId.Text), vs) then

          cdsStockInListSlave.Data := vs; ;//顯示入庫單從表(明細信息)

      end

      else

        ShowMessage('此單不存在!');

    end;

    4)新建入庫單的實現

    procedure TFormStockInList.BtnNewClick(Sender: TObject);

    var

      LId: string;

    begin

      ClearCDSRecord;

      cdsStockInListMaster.Open;

      cdsStockInListMaster.Insert;

      LId := SocketConStockInList.AppServer.GenerateStockInListId;

      LEdtId.Text := LId;

      cdsStockInListMaster.FieldByName('Id').AsString := LId;

      cdsStockInListMaster.FieldByName('GenerateDate').AsDateTime := Now();

    end;

    5)提交功能的實現

    procedure TFormStockInList.BtnPostClick(Sender: TObject);

    var

      LQuerymts: ImtsQueryObjDisp;

      LBar: string;

    begin

      SetSocketConnectionConnect(SocketConQuery);

      LQuerymts := ImtsQueryObjDisp(SocketConQuery.GetServer);

     

      SocketConQuery.Close;

     

      if cdsStockInListMaster.RecordCount > 0 then

        SocketConStockInList.AppServer.UpdataStockInListMaster(cdsStockInListMaster.Delta);

      if cdsStockInListSlave.RecordCount > 0 then

      SocketConStockInList.AppServer.UpdataStockInListSlave(cdsStockInListSlave.Delta);

    end;

    注:本文中ClientDataSet控件的名稱開頭一般為cdsTsocketConnection控件的名稱開頭一般為SocketCon

    三、動態設置TsimpleObjectBroker的服務器列表

    procedure SetSocketConnectionConnect(AValue: TSocketConnection);

      procedure FillAppServerList(ABroker: TSimpleObjectBroker);

      var

        sl: TStringList;

        i, n: Integer;

      begin

        sl := TStringList.Create;

        從配置文件中讀取服務器列表,并保存到sl;

        n := sl.Count - 1;

        ABroker.ServerData := null;

        for i := 0 to n do

        begin

          ABroker.Servers.Add;

          ABroker.Servers[i].ComputerName := sl.Strings[i]

        end;

        sl.Free;

      end;

    var

      LBroker: TSimpleObjectBroker;

    begin

      LBroker := TSimpleObjectBroker.Create(nil);

        FillAppServerList(LBroker);

        AValue.ObjectBroker := LBroker;

        try

          AValue.Connected := true;

        except

          raise Exception.Create('應用服務器連接錯誤!');

        end;

        LBroker.Free;

    end;

    posted @ 2005-10-22 00:51 CowNew開源團隊 閱讀(2261) | 評論 (1)編輯 收藏

         摘要:   凌科網頁精靈開發手記 楊中科 現在網上有大量的網頁特效軟件供網頁制作者使用,但是大多數網頁特效軟件只是羅列了如果將網頁特效代碼添加到html文檔中,比如: “ 第一步:把如下代碼加入<body>區域中:   <span id=liveclock style=position:absolute;left:250px;top:122px> ...  閱讀全文
    posted @ 2005-10-22 00:50 CowNew開源團隊 閱讀(716) | 評論 (0)編輯 收藏

     

    《網絡吸管》開發手記

    網絡確實是個好東西,文章呀,圖片呀什么的都很吸引人。每次上網都能滿載而歸,但是這些資料的收集過程卻很麻煩。對于好文章,每次都要復制、粘貼地在記事本和IE之間切換多次才能保存下來,而且說不定什么時候遇到那種怎么復制也復制不下來的防復制網頁;對于圖片也要點右鍵,選擇“圖片另存為”,再點確定才可以,遇到文件重名問題還要重命名。上網的興致全被打亂了。網上雖然也有“網文快捕”之類的小軟件,但是由于不是為自己“量身定做”的,所以用起來也不是很順手。既然這樣,就自己動手做一個吧,“自己動手豐衣足食”嘛!說干就干!

    設計思想很簡單:監視剪貼板,當發現剪貼板中有新內容時,就根據內容是文字還是圖片來決定不同的保存方式。

    如何監視剪貼板呢?很自然地想到放一個定時器,每隔一段時間檢測一個剪貼板,將剪貼板地內容于上次檢測地內容相比較,如果不同,就說明剪貼板的內容有變化。但是這樣效率太低了,并且定時器的時間間隔也不好把握,間隔太短會降低系統的效率,而間隔太長就有可能漏掉復制的內容。這讓我想起了CPU與外設之間通訊方式中的查詢方式,那么有沒有一種像CPU與外設之間的中斷方式的東西呢?啟動MSDN,搜索ClipBoard,呵呵!終于找到了!是什么呢?聽我慢慢道來!

    為了使應用程序能自動感知剪貼板的變化,windows提供了兩個API函數。使用SetClipBoard可以將窗體注冊到剪貼板觀測鏈中,然后程序就能響應剪貼板的變化消息。剪貼板觀察器是一個顯示剪貼板當前內容的窗口。剪貼板觀察鏈是一系列相互獨立的剪貼板觀察窗口,它們都能夠接受當前發送到剪貼板的內容。

    SetClipBoard的原型是:

    function SetClipBoard(hwndNewViewer:HWND):HWND;

    hwndNewViewer為要注冊的窗體句柄。如果注冊成功,則返回剪貼板觀測鏈中下一個窗體的句柄;如果發生錯誤或無其他窗體,則返回NULL

    如果剪貼板發生變化,windows會向窗體發送WM_CHANGECCHAINWM_DRAWCLIPBOARD消息,觀測鏈中每個窗體都會調用SendMessage將該消息傳送給下一個窗體。當應用程序退出時,要利用API函數ChangeClipboardChain將窗體從剪貼板觀測鏈中移去。其原型為:

    function ChangeClipboardChain(hWndRemove, hWndNewNext:HWND):boolean;

    hWndRemove將要刪除的窗口的句柄, hWndNewNextSetClipBoard返回的窗體的句柄。

    這樣我們只要在程序中等待剪貼板變化的消息即可。當消息到來時,我們應該怎樣得到剪貼板中的內容呢?Delphiclipbrd.pas單元中定義了一個類TClipboard,它封裝了Windows剪貼板,簡化了大量復雜的處理過程。我們在程序中可以直接調用全局函數Clipboard,該函數用于返回TClipboard對象實例,使用這個實例對剪貼板進行剪切、復制和粘貼等操作。下面是TClipboard對象的幾個常用的方法和屬性的簡單介紹:

    方法:

    procedure Clear; 清空剪貼板。

    function HasFormat(Format: Word): Boolean; 查詢剪貼板中是否有指定格式的內容。可以有三種取值:CF_TEXT(文字)CF_BITMAP(位圖)CF_METAFILEPICT(元文件)

    屬性:

    AsText:用于讀寫剪貼板文字內容。

     

    如何給用戶保存下來的圖片文件命名也是個問題。我們可以設置一個全局整型變量,每當保存一個圖片文件時,就令這個變量增加1,將這個整型變量轉換成字符串做為文件名。如果指定的文件名已經存在,就要給文件重命名。最簡單的辦法就是在文件名之前(或之后)加上一個字符串(比如'new'),如果加上這個字符串后還是存在重名的文件呢?這就要用到學編程的人在一開始就學到的一個小技巧:遞歸。這個問題的解決辦法見下面的代碼:

    procedure SaveToPic(APic: TJPegImage; AFileName: string);

    Const PICPLUSSTR = 'new';

    begin

      if FileExists(AFileName) then

        savetopic(ABmp, PICPLUSSTR+AFileName)

      else

          SaveBmpAsJpg(APic, AFileName);

    end;

     

    在實際應用的時候,還應該加上異常處理(如磁盤空間已滿,文件名過長等)。圖片的保存的基本問題已經解決,我們再來看看文字的保存。為了增強程序的靈活性,我們應該使用用戶能方便地將不同地文字保存到不同的文件。繼續沿用上面保存圖片的方式用數字做文件名嗎?當然不可以。一是因為文本文件不像圖片那樣在資源管理器中可以預覽,用戶必須打開文件才能知道文件中保存的是什么內容,如果用戶想在一大堆“1.txt”、“2.txt”……中找自己想要的內容就太麻煩了;二是因為用戶并不要求每次復制下來的內容都保存到單一的文件中,而是要將相關的內容保存到一個文件中。我對這個問題的解決方法是這樣的:

    用戶可以先復制一段文字,然后再按一個熱鍵(比如Ctrl+Alt+S,為什么要選Ctrl+Alt+S做熱鍵呢?后面再說!),這樣用戶以后復制下的文字就保存到以用戶復制的文字做為文件名的文件中。

    記得無數位大師說過:“要將用戶界面與業務邏輯分開。”好吧,就將上面的東西封裝一下,也算是我向OO邁進的第一步吧!(下面之列出了類的部分成員)

      TWebPageSaver = class(TObject)

      private

        FImagePath: string;

        FTextPath: string;

        FImageCount: Integer;

        FTextFileName: string;

        procedure SetImagePath(const Value: string);

        procedure SetTextPath(const Value: string);

      public

        function Save: Boolean;//result is whether the content is saved

        procedure NewTextFile(AFileName:string);

        property ImagePath: string read FImagePath write SetImagePath;

        property TextPath: string read FTextPath write SetTextPath;

      end;

    在用戶界面中,當用戶按下熱鍵Ctrl+Alt+S時,就調用TWebPageSaver.NewTextFile更改文字保存的文件名FTextFileName;當收到剪貼板變化的消息時就調用TWebPageSaver.Save保存剪貼板中的內容。另外還有ImagePathTextPath等屬性,可以由用戶來更改圖片、文字的保存路徑。

     

    核心代碼已經完成,來做一下用戶界面吧!仿照著“windows優化大師”我做了如下的界面:

    ns1.jpg

     

     

     

     

     

     

    很漂亮吧?左邊我用的是TSpeedButton組件,右邊是TNotePage組件。當用戶點擊一個TSpeedButton時,調用TNotePage.ActivePage := '頁面的代號'就可以激活相應的配置界面。這個軟件需要在后臺運行,那么就讓它在平時縮小到系統托盤吧!將程序縮小到系統托盤很容易做到,網上有很多這樣的示例代碼。我手頭有一個控件cooltray4.3可以用來實現系統托盤的功能,我就懶得自己再去寫代碼了。

    軟件運行一切良好。不過一直令我耿耿于懷的就是網上那種防復制的網頁:不管你怎么拖動鼠標,那些文字就是無法被選定。仔細想一想,既然文字能夠在IE上顯示就一定可以得到它們。在MSDN中找了半天,才找到解決方法。可以通過ShellWindows集合來代表屬于shell 的當前打開的窗口的集合,而IE就是屬于shell的一個應用程序。用CoShellWindows.Create得到當前打開的shell的接口(IShellWindows),調用接口的Count屬性得到當前打開的shell的數量,然后遍歷這些窗口,嘗試從接口中取出IWebbrowser2接口(通過ShellWindow.Item(I) as IWebbrowser2這樣的接口類型轉換方式),如果結果不為nil說明這個窗口是IE窗口。之后只要調用IWebBrowser2接口的相應方法即可得到窗口中的文字、URL、標題等內容了。

    示例代碼如下:

    {需要使用mshtml,SHdocvw兩個單元}  

    var

     ShellWindow : IShellWindows;

     WebBrowser : IWebBrowser2;

     I, ShellWindowCount: integer;

     HTMLdocument : IHTMLdocument2;

     URL, Title, Text:string;

    begin

      ShellWindow := CoShellWindows.Create;

      ShellWindowCount := ShellWindow.Count;

      for I := 0 to ShellWindowCount-1 do

      begin

        WebBrowser := ShellWindow.Item(I) as IWebbrowser2;

        if WebBrowser <> nil then

            begin

                HTMLDocument := WebBrowser.Document as IHtmlDocument2;

                URL := URL;

                Title := HTMLDocument.title;

                Text := HTMLDocument.body.outerText ;

                ShowMessage(URL+Title+Text);

            end;

      end;

      ShellWindow := nil;

    end;

     

    我們定義一個記錄類型:

      TWebPageRecord = record

        URL: string;  //保存網頁的URL

        Title: string;//保存網頁的標題

        Text: string; //保存網頁的文字

      end;

     

    然后定義一個TWebPageRecord類型的數組FWebPageRecordArray,大小定位20吧(我想一般人不會打開20個以上的IE吧):

    Const  MAXPAGECOUNT = 20;

    ……

    FWebPageRecordArray : array [0..MAXPAGECOUNT-1] of TWebPageRecord;

    在遍歷IE窗口時,向數組中的元素的相應字段復制即可。

    對這個復制防復制(好拗口呀:))網頁的功能也封裝成一個類吧!

    type

      TWebCracker = class(TObject)

      private

        FWebPageRecordArray : array [0..MAXPAGECOUNT-1] of TWebPageRecord;

        FWebPageCount: Integer;

      public

        procedure SnapShot;

        function GetWebText(AIndex:integer): string;

        function GetWebTitle(AIndex:integer): string;

        function GetWebURL(AIndex:integer): string;

        procedure Clear;

        procedure Refresh;

        function GetWebPageCount: Integer;

      end;

    在用戶界面中,可以通過調用TWebCracker.SnapShot;來對打開的IE窗口進行遍歷,并保存到FWebPageRecordArray這個數組中。通過TWebCracker.GetWebPageCount方法可以得到FWebPageRecordArray中保存的頁面的個數,通過GetWebTextGetWebTitleGetWebURL就可以得到指定頁面的文字、標題或是URL

    一切都已經搞定了!爽!

     

    通過編寫這個小軟件,我是收獲頗豐呀!除了學到了上邊這些技巧外,我還有一些小的經驗,愿意與大家分享:

    1、為用戶著想,讓用戶舒服

    用戶是上帝嘛!以那個Ctrl+Alt+S熱鍵來說吧:一般用戶上網都是右手握鼠標,空下來的只有左手。小拇指按Ctrl,大拇指按Alt,食指剛好能按到S鍵,不費一點力氣!

    2 良好的編碼習慣

    1)不要出現魔術數

    TWebCracker定義的那個FWebPageRecordArray數組來說:

    Const  MAXPAGECOUNT = 20;

    ……

    FWebPageRecordArray : array [0..MAXPAGECOUNT-1] of TWebPageRecord;

    別人一看MAXPAGECOUNT就知道是什么意思,而如果你寫成:

    FWebPageRecordArray : array [0..19] of TWebPageRecord;

    估計除了你自己沒有人能夠知道19到底是什么意思。

    2)用sender的方式增強代碼的健壯性

    procedure TMainfrm.CBAutoRunClick(Sender: TObject);

    Const

      SIGNINREGISTRY = 'WebSuction';

    begin

      if (Sender as TCheckBox).Checked then 

         AddToAutoRun(Application.ExeName,SIGNINREGISTRY)

      else DelAutoRun(SIGNINREGISTRY);

    end;

    這樣即使Checkbox1改了名字也不怕。

    又如:

    procedure TMainfrm.N1Click(Sender: TObject);

    begin

      if (Sender as TMenuItem).Caption = '暫停(&S)' then

        begin

          (Sender as TMenuItem).Caption := '開始(&R)';

          FWebPageSaver.Pause;

        end

      else

        begin

          (Sender as TMenuItem).Caption := '暫停(&S)';

          FWebPageSaver.ReStart;

        end;

    end;

    3)不要直接使用Tform2單元的全局Form2變量,那樣就破壞了封裝性

    procedure TMainfrm.SBNextClick(Sender: TObject);

    var

      LSelectedIndex : integer;

      FormDisplay : Tform2;

    begin

      LSelectedIndex := LBWebPage.ItemIndex;

      if LSelectedIndex <> -1 then

      begin

        FormDisplay := Tform2.Create(self);

        FormDisplay.SetContent(FWebCracker.GetWebText(LSelectedIndex));

        FormDisplay.Show;

      end;

    end;

    TForm2中定義 SetContent方法

    procedure TWebCrackfrm.SetContent(AText:string);

    begin

      Memo.Clear;

      Memo.Lines.Add(AText);

    end;

    posted @ 2005-10-22 00:45 CowNew開源團隊 閱讀(468) | 評論 (0)編輯 收藏

         摘要:   現在網上有很多提供主頁空間的站點,但是大部分低價位的站點只提供靜態HTML文檔的功能,不支持ASP、PHP等動態網頁技術。如果您像在您的主頁上放上您喜歡的文章,那么需要一個一個鏈接的做。如果您刪除了某篇文章或者想添加某篇文章,那么需要做很多改動,牽一發而動全身。   凌科文章動態發布系統就是為你解決這個問題而開發的軟件。使用本軟件后您可以輕易生成下面效果的網頁。 //...  閱讀全文
    posted @ 2005-10-22 00:42 CowNew開源團隊 閱讀(926) | 評論 (0)編輯 收藏

    僅列出標題
    共30頁: First 上一頁 22 23 24 25 26 27 28 29 30 下一頁 
    主站蜘蛛池模板: 精品国产日韩亚洲一区91| 亚洲美女中文字幕| 国产精品无码亚洲一区二区三区| 免费观看激色视频网站bd| 欧洲亚洲国产清在高| 精品国产免费一区二区三区| 亚洲免费日韩无码系列| 男人和女人高潮免费网站| 亚洲人成影院在线观看| 精品97国产免费人成视频| 国产亚洲成人在线播放va| 成人网站免费大全日韩国产| 亚洲精品无码久久千人斩| 成全视频高清免费观看电视剧| 亚洲人成网站在线播放vr| 久久免费视频网站| 亚洲福利视频一区二区三区| 久久久久国产精品免费免费搜索| 亚洲欧洲免费无码| 亚洲区日韩区无码区| 大地资源在线资源免费观看| 久久精品国产亚洲AV香蕉| 国产精品免费精品自在线观看| 亚洲人xxx日本人18| 国产无遮挡又黄又爽免费视频| 日本一区二区三区在线视频观看免费 | 亚洲午夜久久影院| 毛片a级毛片免费播放100| 边摸边吃奶边做爽免费视频99| 国产成人亚洲综合| 午夜影院免费观看| 亚洲日韩AV一区二区三区中文| 亚洲天堂免费在线视频| 无码人妻一区二区三区免费n鬼沢 无码人妻一区二区三区免费看 | 少妇人妻偷人精品免费视频| 亚洲入口无毒网址你懂的| 亚洲av区一区二区三| 99爱免费观看视频在线| 亚洲gay片在线gv网站| 国产成人A人亚洲精品无码| 曰批全过程免费视频在线观看|