Translate

2010/12/15

BorlndMM.dll,我們分手吧

FastMM4本身也帶了一個BorlndMM.dll,也有可編譯的專案(4.94)
如果要再編譯,仍然要將相依的pas、dll、inc等都放入相同目錄中即可

設定inc可對產出的BorlndMM.dll做微調

我個人比較懶,所以我就將log、mem leak提示功能都關了,想看到mem leak狀況時再加入fastmm吧。

最後,我就跟BorlndMM.dll分手了,但換上的還是叫BorlndMM.dll……

BCB6 + FastMM4 搭配上應注意的地方

在網路上找了很久,總算是給我試出來了。

過程當中最麻煩的還是在FullDebugMode開啟後所帶來編譯問題,不是可編譯無效果,就是完全無法編譯。不論是參考對岸常用的4.78版,或是最新的4.97版,結果都是不正常的。

最後是參考這個網址:좀 황당한 이야기

2010/12/04

入行4週年紀念,程式設計不敗法門傳授!-心法篇-

基本上,這個主題跟詐騙沒啥兩樣,那個那個!太資深的請離開;咦!那個拿關刀的那位,這邊不是武鬥場啊!請不要拆台啊!

咳!
打鬧到這邊結束,來開始介紹如何做一個「不敗」的程式設計師吧!

2010/12/03

DBeXpress / DataSnap 排序,真是令人意外的難排

剛剛翻了一下Delphi 2006數據庫的書(电子工业出版社.李维著《Delphi 2006高效数据库程序设计:dbExpress篇》),有提到排序的結論:(詳見此書的P.112頁)

2010/11/22

最近朋友從日本秋葉原帶回來的夢幻逸品

上星期好友去日本出差辦私事(?),回程的時候經過秋葉原,看到一堆宅男在排隊,在好奇心的趨使下,排了半小時,就排回來了高級宅男小吃,廢話不多說,讓我們來看看日本宅男有多幸福吧!!!

2010/11/13

最近專案開發的一些三兩事

網路方面:
參考了Indy10.0.x的寫法,寫出了簡易的indy server / client 聊天程式
並且應用到專案之中,按照網友的說法,應該是能撐到500人同時連線沒有問題。

執行緒方面:
在queue與公用變數做一個thread safe的處理,參考了ktop thread queue demo,成功將這個概念導入到專案中,專案應該就可以更穩了吧。

資料庫方面:
又重溫了TDataSetProvider和TClientDataSet的功能;
TDataSetProvider :
進行多表處理時必須使用DataSetProvider下自訂的sql指令來完成細部處理,但這時就必須放棄DataSetProvider自己定義的工作。

TClientDataSet :
發現Filter + Filtered可以替代SQL篩選功能,但僅限於現有資料,在自訂資料集的場合仍然是有些無力
雖然最後仍然是用 for + if 來完成temp table的處理,但未來有機會一定要再來試一下這項功能。

2010/11/04

Grand DINK 150保險絲規格

800mA / 250V,有些手機充電器還不能用,整個就是小啊!

AO751h在win7下真的支援opengl囉!

請參考這邊

2010/11/13 補充:Win7 支援了,但效能仍然很差、 AERO一樣不支援;更慘的是,原本的硬解功能全沒了,失去的比得到的還要多啊~~~~~

2010/09/28

Firebird 流水號可能遇到的問題

1. CREATE SEQUENCE 和 CREATE GENERATOR 是一樣的.
2. 必須搭配 Trigger 使用.
3. 刪除一列後會造成 Sequence 破碎 (可以再開一個table來存刪除的 Sequence,再新增的時候可以參考之)

2010/09/26

[轉貼]Delay的寫法

資料來源
void Delay(int iMilliSeconds)
{
  int iStart;

  iStart = GetTickCount();
  while (GetTickCount() - iStart <= iMilliSeconds)
    Application->ProcessMessages();
}

用後感:
利用了Win32 API來進行讀秒的工作,真是大絕!
在與多執行緒搶行程的時候,可以用這個來避免Hold

2010/08/31

PDF to PocketMod 自製口袋書的奇妙軟體

資料來源:The PocketMod

緣起:
最近覺得開會時間總是很長,總想在筆記本放些資料,這樣在開會時就不用老是放空了。(好孩子不要學唷)
A4紙實在太大太明顯,一定要縮小才行,可是縮小後還要自己剪裁,如果有口袋書就方便多了,這時,有個軟體叫[PDF to PocketMod],可以製作很簡單的口袋書哦!
以下是執行後的畫面:


操作方式很簡單,只要執行程式後,在[Output Page Size]選擇要輸出的紙張大小後,選擇欲轉換的PDF檔,之後再按下[Save as PocketMod]就可以了。

完成後就會呼叫PDF Reader開啟轉好的PDF囉。




官方網站提供的折紙影片:

2010/08/26

ACER AO751h 使用SetFSB超頻

參考資料:
1. Noda's Dev Blog
2. How come ASUS1101HA's Z520 overclocks to 1.73Ghz and 751h no

一、有線網卡和CCD必須關掉,不然可能會當機
二、(選配)有個好用的桌面控制程式:下載 a1ctl v1.0. (Win7需再下載 fix )
三、使用SetFSB設定如下圖即可

2010/08/25

受傷歸受傷,身體還是要鍛練的

自從上個月因為練合氣道後滾翻的左肩 + 踩到踏踏米縫而導致的左腳受傷
(一整個遜爆)


就完全中止去合氣道的練習了。到目前為止還在持續受傷ing……真希望能快快好啊。

眼看肥滋滋 就快看不到自己的小gg 的肚子,心想著一定要運動一下。於是,貼心的小公主就買了游泳池的月票,一整個「就感心」。

所以,我要努力回到我70kg玉樹臨風的樣子啦!

這應該是小公主想要變成的樣子……(羞)
圖為【星野亞希】

2010/08/19

VMWARE 6.X use exFat

fix  "The destination file system does not support large files." & "fail lock disk 
1. Edit *.vmx
2. Add:
  disk.locking = "FALSE"
  diskLib.sparseMaxFileSizeCheck= "false"
3.save file.

軟體工程,猶如人飲水,冷暖自知



最近看了些有關設計模式的書籍,老實說,在上位的人一點也不在乎你所做的文章,只在乎是否可以短期做出成品,常常造成,程式設計師寫個半死,想個半死,老闆一點也不care的情況。

就好像「下午的一齣戲」歌曲裡的歌詞:台跤無一聲好 台頂是攏全雨 (台下沒有人欣賞,台上的人賣力演出)。這似乎是做設計的一種宿命?

好吧,繼續下雨去。

2010/08/13

深入資料庫之美學...這本好像不錯耶~~~

前幾天在逛網,看到有blog在介紹資料庫理論的一本書

C.J.Date 的新書 ─ 深入資料庫之美學



原來它的英文名字是「Database in Depth」,彼岸網站上也有相關的電子書供應 ,不過是原文的chm格式…以我的英文程度,k完大概要花上個數年時間吧!(汗)

不過Google有和台灣歐萊禮合作,在「Google電子書--深入資料庫之美學」有提供樣品給網友試讀。

不出所料的,讀了前幾頁就暈倒了……可見是修行還不夠啊~~~(淚奔)

到底該不該買這本書呢……………?

另外,Indy網站也有出「Indy in Depth」,不知道中文書名(如果有出的話)會不會是「深入Indy之美學」呢?(笑)

要用indy作個網路聊天室?要有踩地雷的心理準備……

前一陣子又想練習一下 Indy 元件組,不經意發現

Sever Side Chat Application with Borland Delphi/Indy
有提供範例!


馬上下載它的範例來看看。


想不到code亂就算了,還error一堆


debug到快翻過去了,還沒搞定!


D7+Indy 10.0.52版本


用法與10.2.3差了一大截!


練習痛苦指數可說是破表呀!


掃雷ing

2010/07/23

現在的人是靠消遺別人來得到成就感?來滿足自己?

最近這一陣子感受非常強烈

每次聊天的過程,我提的意見總是被消遺,被諷刺,被嘲笑。

對方總是把自己說的是如此地有見地。

對這種人的真情相待只能得到對方充滿不屑的眼神。

偏偏卻又是天天見面的同事"們",不只一個就是了。

或許這是另一種公司的文化吧。我見識到了。

 我沒這麼不堪好嗎!他馬的!





「不跟你們好了啦!」 (整個氣勢都沒了)

最後,補上某當機的圖片
















這應該是新版的出氣包吧?
哪裡有賣呢?

[翻譯]File I/O (上)

File I/O
by Kent Reisdorph


在某種程度上,每個程式設計師都會需要做些檔案寫入和輸出(File I/O)的工作。
在這邊我們只探討File I/O,不包含資料庫檔案的處理(那個看資料庫實作範例就可以了,資料庫程式設計可是C++ Builder的專門科)。

不管怎說,不論是現在還是以後,你都會需要專業的File I/O。

在這篇文章將展示File I/O的寫入和輸出動作。

2010/07/07

[翻譯]玩轉你的記憶體 -- 使用TMemoryStream

雖然是1998年的文章,但2010年看到這篇文章的我,還是覺得有很大的收獲,在這邊分享出來
原文:Manipulating memory with TMemoryStream
譯文:愛抱怨本鋪. eden的雜念溜

Manipulating memory with TMemoryStream

C++ Builder Developer's Journal 雜誌3月號裡有篇"File I/O",講述TFileStream類別和如何使用該類別讀寫在磁碟中的檔案。

但有些時候,與其使用磁碟,你會比較想在記憶體中處理較大的資料。
好消息是TFileStream有個親戚叫TMemoryStream,正好是為此目的而設計。

在本篇文章中,我們將展示如何使用TMemoryStream去處理記憶體,就和我們3月刊的檔案處理方法一樣。
我們將證明如何使用與檔案I/O相同的方法去讀寫記憶體。

聽起來不錯!但為什麼我要這樣做啊?


2010/06/25

RAD Studio 2010 + IntraWeb 10.0.0 + jQuery = 100%成功執行方法!

RAD Studio 2010 + IntraWeb 10.0.0 + jQuery = 100%成功執行方法
標題很聳動,但其實也是從 Intraweb中引入外部js文件 看來的。
另外,Intraweb 与Jquery结合 --->使用方法 這篇,我試不出來,如果有人知道這篇所提的「腳本」是什麼東西,也麻煩回應一下唷!

方法可以說是一模一樣,不過遇到了些奇怪的問題,先把步驟貼上來吧:

1 建好js文件,在這里人比較喜歡的是用jquery 輕巧強大.然後放在files目錄下面名為jquery.js,這裡有一點要注意的是一定要入在files文錄下面,其它的目錄無效.

2 在Form的ExtraHeader屬性中添加如下代碼

 <script type="text/javascript" src="/files/jquery.js"></script>

 當然啦你也可以在Form 的onCreate事件中添加

 self.ExtraHeader.Add('<script type="text/javascript" src="/files/jquery.js"></script>');
好了到此為止,初始化的工作就做好了,然後直接的在相應的控件上寫js代碼就可以了,例如button的click事件裡面寫下如下代碼

        $("#IWEDIT1").attr("value","good");

就可以使名為iwedit1的值變為good

哈哈,相信一些有識之士能用服務器功能強大的iw與客戶端功能強大的js庫做出很多意想不到的事情哦

======================================
實作後:
一、以上步驟照抄的我,發現它不會變good……(暈)
二、我下載的是jquery-1.4.2.js,改名為jquery.js
三、不會動就是不會動 (倒)

在試了好幾天後,我又去下載了jquery-1.4.2.min.js,這次不 跟你好了 改名了

結果,它居然就正常了耶!(炸)

不信邪,又再把之前的jquery-1.4.2.js改回去(沒改名喔) ---------正常!(再炸)

最後,再將jquery-1.4.2.js改名為jquery.js,再測!-------------還是正常!(趴)

看來果然是我太累了…(逃)

IW真的做出了很多我意想不到的事情啊!(抖~)

最後的最後,補上很ok的一張圖,貼完收工!別說我詐騙你們啊!(笑)

2010/05/26

DBEXPRESS 1.0/2.0 不支援 SQLDialect 3

最近在玩Firebird 2.1.3,練習的對象是它內附的Example
當一切都部署好後,SQLQuery Open!
居然給我跳出一個大錯誤:
"Client SQL dialect 1 does not support reference to BIGINT datatype"

傻眼了,去找了一下,發現也有網友遇到這個問題
DBX Driver也有加入 SQLDialect=3 ,沒效果。

後來跑去下載個 InterXpress for Firebird 回來,換上driver後,搞定。

嗯…看來BCB6也到了極限了。

2010/05/06

AO751h搭配上Win7

最近終於下定決心要重灌系統
聽說Ao751h硬體有支援到Win7,索性就裝起來玩一玩
發現WIN7下的驅動真的有比較好,速度上也快了許多。

有時間再來發其他的心得吧

2010/04/04

ACER AO751h : 痛苦的影像播放過程

買這台小筆電的使用者一定會遇到的這個問題

現在隨隨便便的影像都是高清,連著重在網路傳輸的rmvb, wmv也都跟著高清,沒事也來個xxxx * 720,連看個血脈噴張的 謎片 阿凡達也都變成幻燈片展示,真是夠囉!

可是呢
ATOM z520這個晶片組可以硬解H.264及MP4的影像

所以只要轉個檔就沒問題了吧!

後來在網路上找了兩種轉檔程式,還不錯用

1. HandBrake (是叫鳳梨罐頭嗎?只有這套解出來的h.264才能讓751h開硬解,原因不明)
2. Extra.Movie (吳文成大師寫的一套影音轉檔工具,也支援mp3獨立抽出或是剪輯,很棒的軟體。不過轉出來的h.264 751h晶片認不出來,所以不能硬解)

2010/03/24

ACER AO751h安裝Windows7

嗯,剛剛打電話給客服人員,得到以下的回應
Q. 安裝win7後,原有的還原磁區還能用嗎?
A. 不行。

Q. 不能再用還原磁區,那怎麼辦?
A. 建議你直接做成還原光碟,需要還原時只要用那張光碟就可以了。

Q. 還原是連備份磁區一起還原嗎?
A. 不是,只有單一磁區。

Q. 開機時的ALT + F10功能鍵可以用BIOS手動關閉嗎?
A. BIOS沒有這個項目。

Q. 751h有支援XP-mode嗎?
A. 沒有。

以上,ACER的工程師真的…話很簡潔,可能是夠專業吧。

那個還原磁區好像只要重灌後就不能用了,很雞肋。
從以上解答可以知道,AO751h的VT功能確定是被關起來的!

嗯...真的要好好考慮換系統的事情了…

[轉載]用OpenOffice Writer製作一本包含封面、目錄、內容及頁數的書

資料來源:用OpenOffice Writer製作一本包含封面、目錄、內容及頁數的書

如何讓OpenOffice Writer自動加入目錄,並製作成包含封面、目錄、內容及頁數的書,是一個讓我困擾已久的問題。以下的方法,是我今天在製作講義時才摸索出來,希望能對各位OpenOffice的愛用者有幫助,如果文件有問題或是有更方便的方法也歡迎提出。

我的目標如下:
1. 封面:不加頁數
2. 目錄:有章節編號及名稱,自動
加上頁數
3. 內容:分章、節、小節、subsubsection,從1開始編頁碼

首先附上我製作的例子:odt pdf
以下的說明請參考這兩個例子。

1. 設定頁面樣式

為了讓不同的樣面採用不同型式的頁碼,我們必須先插入不同樣式的頁面。首先開啟一個新的文字文件,一開始預設的頁面樣式為標準。從上方工具列中選取插入=>手動換行,會出現如下圖的視窗。



選取換頁、樣式為標準變更頁碼為1,再用同一的方法新增一頁,但這次選擇樣式為目錄。但是這樣我們仍然缺少封面,因此再從下圖中紅線框起的部分,按右方的三角形下拉選單,再選擇更多,會出現如下下圖的視窗,雙擊首頁即可將所在的頁面樣式轉換為首頁。






2. 插入頁尾及頁數
從上方工具列中選取插入=>頁尾,選擇標準目錄就好了,因為我們不想在首頁(封面)顯示頁數。在頁尾的方框中,自上方工具列中選取插入=>欄位指令=>頁碼,即可在除了首頁以外的每一頁最底下顯示頁碼。如果想要讓目錄的頁碼使用別的格式,請在頁碼上按滑鼠右鍵選擇欄位(有時要多按幾次,不容易按到),會出現如下圖的視窗,在這裡面就可以選擇想要的頁碼格式。



3. 變更段落格式
我們在此要先變更一下段落樣式,這些格式是為了給chapter、section、subsection及subsubsection用的(我不知道subsubsection中文要怎麼翻,所以乾脆用英文)。從上方工具列選取工具=>章節編號,會出現如下圖的視窗。我是將標題1設定為第1級的格式,並且在分隔符之前加上、在之後加上,這樣顯示出來的結果就會是第x章。相同地,我再將標題2設定給第2級使用,不過這次就不加上文字,而是讓它顯示為x.x。我只有設定到標題4,因為我通常不會用到subsubsection以下的編號。



4. 輸入章節標題
再來就到頁面樣式為標準的頁面中輸入內容,可以先打好章的標題之後再將滑鼠游標移到所在的那行,再從步驟2中第二張圖所標示的地方改變段落樣式。如果是的標題,則改為標題1的標題則改為標題2,依此類推。


5. 插入目錄
最後到頁面樣式為目錄的頁面中,從上方工具列中選取插入=>目錄=>目錄,會出現如下圖的視窗。在第一個分頁中可以決定標題及要顯示到多少級,我將它設定為3級,也就是不顯示subsubsection。另外,我通常會將不允許手動變更去掉,這樣等一下出了任何狀況才可以手動修改。



在第二個分頁中,可以決定顯示的格式。我通常將E#E之間加入10個空格,讓章節編號和標題間有點距離。




到此為此算是大功告成了。再來我們可以在檔案=>屬性中加入一些此文件的相關資訊(如下圖)。



之後再從檔案=>匯出成PDF檔,將文件轉成pdf檔。在按下匯出之後,會出現如下圖的視窗,我們可以在此決定這個pdf檔相關的性質。





最後,用pdf reader開啟剛才輸出的檔案來看看。因為有加入章節編號的關係,所以pdf檔中已經建立好書籤了,看起來就很專業吧!

2010/03/23

Win7執行BCB6時,發生問題的解決辦法

BCB6可以安裝在Win7上面,不過在開啟BCB6時,會告訴你說ooxx的檔案無法開啟,而導致Project開不了。

由於Win7的架構與Vista幾乎是一樣的,所以解決方式應該大同小異

所以參考了
BCB6:
在Vista執行BCB6

Delphi:

測試過之後,真的可以用耶!
呵呵呵!

附上執行結果圖:
那麼…就再繼續用BCB6吧
不過畫面還是鳥鳥的…等存夠錢再來升級一下吧 ^ ^

2010/03/22

放棄…也算是勇於面對自我吧?

準備領隊導遊的考試也有了一段時間,其間也對觀光資源概要做了很多很多的研讀
但不知怎麼的,每次的考古題都可以考出很多從沒看過的題目

平均一直都在3x附近排徊…而實務一、實務二也因為長時間沒複習而只有約5x分的水平。

這樣的情況,叫我怎麼去應考呢!!!

猜答案都沒猜對過的經驗來看,放棄應該是明智的選擇吧。

傳說明年度及格分數會調高到75分,看來這張證照離我真是越來越遙遠了呀~~~~~

2010/03/16

[轉載] C++ Builder: Use a mutex to achieve synchronization

在網路上有看到一篇:C++ Builder中引用API函数禁止应用程序多次启动
看得不是很明白
於是找到另一篇,C++ Builder Developer's Journal / Use a mutex to achieve synchronization
但編排不是很好,所以我有稍微做了一下程式碼的排版,其它內容一字不變地轉載:
January 1998
Use a mutex to achieve synchronization
by Sam Azer

Over the past few months, a few people on the CPB-Thread listserv have asked how to prevent more than one instance of an application from being started. (To subscribe to CPB-Thread, visit www.cobb.com/cpb.) Several people have worked very hard on a variety of answers to this question. It seems, though, that the simplest solution is one suggested by members of Borland's TeamB on their news server: a named mutex. As you know, Windows 95 provides a number of built-in functions for running multiple tasks and threads within a task. Accordingly, a group of Synchronization functions is available to ensure that your tasks and threads are able to work together effectively.

One of the more common problems in a multitasking environment is resource sharing. If you're using a resource--for example, a serial port--you don't want somebody else to start using it before you're finished. The standard solution to this problem is for you to get a mutual exclusion lock (mutex) on the resource. If you're able to get the lock, you can use the resource. If, while trying to lock the resource, you find that somebody else has it--you must wait.

In this article, we'll build a small and very simple function to return true if an instance of a program is already running. To do this, we'll use a simple named mutex. (You can download the code from this article at www.cobb.com/cpb.) Let's start by looking at how you can use a mutex.


Using a named mutex
A mutex is a very simple object. It has a name, access rights, and a state. The name must be unique among all mutex, semaphore, and file-mapping objects. In most cases, the access rights will be MUTEX_ALL_ACCESS. The state can be Owned or Not Owned. If you create a resource that can be used by only one caller at a time, you'll probably also create a mutex for it. In this case, your callers try to open the mutex to see if the resource exists. Once they have a valid handle to the mutex, they use wait functions to gain ownership of the resource and start using it. Wait functions sleep until a mutex isn't owned, then take ownership of it and use the resource. (You can optionally place a time limit on a wait function.) Eventually, the caller will release the mutex, marking it not owned and available to the next caller. In this way, all callers wait to take ownership of the resource when they need it and release it when they're finished. If a caller has no further need for a resource, the mutex handle can be closed.

Once a mutex exists, any tasks trying to create it again will get a handle to it and an error already exists error. If a task ends, all the mutex handles that it owns are closed. When all tasks have closed their handles to a mutex, it's destroyed. Therefore, a single call to the CreateMutex() function is all you need to find out if an instance of an application is already running!

Using CreateMutex()

The CreateMutex() function takes only three parameters: a pointer to a security descriptor, a flag to request immediate ownership, and the name of the mutex to create. It returns a HANDLE. It ignores the pointer to the security descriptor under Windows 95. Under Windows NT, you can get default security settings by passing a NULL pointer. The mutex name is simply any unique null-terminated string (up to MAXPATH characters in length). If the returned HANDLE is null, something undesirable happened. In any case, GetLastError() should return zero to indicate that the mutex was created. A value of ERROR_ALREADY_EXISTS indicates that the mutex already exists. Use SysErrorString() to translate the other error codes into English.

By now you've probably realized that there really isn't much to it--you can very easily detect an existing instance of an application using this method. Listing A shows the source code for one way to do it.

Listing A: Detecting another instance of an application

//--------------------------------------------
#include
#pragma hdrstop
//--------------------------------------------
USEFORM("OneOnlyForm.cpp", Form1);
USERES("OneOnly.res");
//--------------------------------------------
// the name of the mutex for this program
const char *MutexName = "OneOnlyDemo";
//--------------------------------------------
HANDLE CheckInstance( const char *Name )
{
// 1st: create mutex. Request ownership.
HANDLE Mutex = CreateMutex(NULL,true,Name);
// Next, error result - should be zero
int r = GetLastError();
// if r != 0, probably ERROR_ALREADY_EXISTS
if ( r != 0 )
return 0; // disaster or another instance
return Mutex; // else, return the handle.
}
//--------------------------------------------
WINAPI WinMain (HINSTANCE,HINSTANCE,LPSTR, int)
{
HANDLE Mutex = CheckInstance( MutexName );
if ( !Mutex )
{
MessageBox(HInstance, "Another Instance is running!", "Sorry", MB_OK );
ReleaseMutex( Mutex );
return 1;
};

try
{
Application->Initialize();
Application->CreateForm(__classid(TForm1),&Form1);
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
return 0;
}
//--------------------------------------------

Wrap up
Do a keyword search for Synchronization in the Win32 (Platform) SDK Help files for detailed information on the functions available for synchronizing--they're quite handy. In many cases the code presented in this article is enough to prevent problems from occurring between two instances of a simple database program. However, for MDI applications you'll probably want to send a message to the original instance. Watch for an article on inter-process communications in a future issue of C++Builder Developer's Journal.

哼…TDataSetProvider…真是被你打敗了呀

不知道是不是BCB6過於老舊,對ClientDataSet做Edit工作(SQL's Update)
一直很不順利,老是出現:
"Table unkown 'TableName'"

於是丟了個SQLMonitor去除錯
結果從SQLMonitor查到的語法是這樣的:
update "TableName"
set 'Field' = ?
where
set 'Field' = ?

[轉載]Delphi ListView基本用法大全

Delphi ListView基本用法大全

作者:不明,取自CSDN轉載





//增加項或列(字段)

ListView1.Clear;
ListView1.Columns.Clear;
ListView1.Columns.Add;
ListView1.Columns.Add;
ListView1.Columns.Add;
ListView1.Columns.Items[0].Caption := 'id';
ListView1.Columns.Items[1].Caption := 'type';
ListView1.Columns.Items[2].Caption := 'title';
ListView1.Columns.Items[2].Width := 300;
Listview1.ViewStyle := vsreport;
Listview1.GridLines := true;
  //注:此處代碼也可以直接在可視化編輯器中完成,也可寫成以下這樣

begin
  with listview1 do
  begin
    Columns.Add;
    Columns.Add;
    Columns.Add;
    ViewStyle := vsreport;
    GridLines := true;
    columns.items[0].caption := ' 進程名';
    columns.items[1].caption := '進程ID';
    columns.items[2].caption := ' 進程文件路徑';
    Columns.Items[0].Width := 100;
    Columns.Items[1].Width := 100;
    Columns.Items[2].Width := 150;
  end
end;
//增加記錄
with listview1.items.add do
begin
  caption := '1212';
  subitems.add('hh1');
  subitems.add('hh2');
end;

//刪除
listview1.items.delete(0);
//從數據庫表裡讀取數據寫入Listview
var Titem: Tlistitem; //此處一定要預定義臨時記錄存儲變量. begin ListView1.Items.Clear; with adoquery1 do begin close; sql.Clear; sql.Add('select spmc,jg,sl from kcxs'); Open; ListView1.Items.Clear; while not eof do begin Titem := ListView1.Items.add; Titem.Caption := FieldByName('spmc').Value; Titem.SubItems.Add(FieldByName('sl').Value); Titem.SubItems.Add(FieldByName('jg').Value); next; end; //刪除 ListView1.DeleteSelected; end; end;
//如何取得ListView中選中行的某一列的值

procedure TForm1.Button2Click(Sender: TObject);
begin
  ShowMessage(ListView1.Selected.SubItems.Strings[1]); //返回選中行第三列中的值
end;

showMessage(listView1.Selected.Caption); //返回選中行第一列的值.

//第1列的值: - - > > > 
  ListView1.Selected.Caption
//第i列的值(i > 1): - - > > > 
  ListView1.Selected.SubItems.Strings[i]
ListView1.Items.Item[1].SubItems.GetText); //取得listview某行某列的值 Edit2.Text := listview1.Items[i].SubItems.strings[0]; //讀第i行第2列 //返回選中行所有子列值.是以回車符分開的,你還要從中剝離出來你要的子列的值。 showMessage(ListView1.Selected.SubItems.GetText); //ListView 簡單排序的實現 //ListView 排序 //怎樣實現單擊一下按升序,再單擊一下按降序。 function CustomSortProc(Item1, Item2: TListItem; ColumnIndex: integer): integer; stdcall; begin if ColumnIndex = 0 then Result := CompareText(Item1.Caption, Item2.Caption) else Result := CompareText(Item1.SubItems[ColumnIndex - 1], Item2.SubItems[ColumnIndex - 1]) end; procedure TFrmSrvrMain.ListView1ColumnClick(Sender: TObject; Column: TListColumn); begin ListView1.CustomSort(@CustomSortProc, Column.Index); end; //=============================================================== //增加 i := ListView1.Items.Count; with ListView1 do begin ListItem := Items.Add; ListItem.Caption := IntToStr(i); ListItem.SubItems.Add('第 ' + IntToStr(i) + ' 行'); ListItem.SubItems.Add(' 第三列內容'); end; //按標題刪除 for i := ListView1.Items.Count - 1 downto 0 do if ListView1.Items[i].Caption = Edit1.Text then begin ListView1.Items.Item[i].Delete(); //刪除當前選中行 end; //選中一行 if ListView1.Selected <> nil then Edit1.Text := ListView1.Selected.Caption; // listview1.Items[Listview1.Items.Count -1].Selected := True; // listview1.Items[Listview1.Items.Count -1].MakeVisible(True); procedure TForm1.Button2Click(Sender: TObject); // 選擇第一條 begin listview1.SetFocus; listview1.Items[0].Selected := True; end; procedure TForm1.Button1Click(Sender: TObject); // 選擇最後一條 begin listview1.SetFocus; listview1.Items[Listview1.Items.Count - 1].Selected := True; end; //這是個通用的過程 procedure ListViewItemMoveUpDown(lv: TListView; Item: TListItem; MoveUp, SetFocus: Boolean); var DestItem: TListItem; begin if (Item = nil) or ((Item.Index - 1 <> = lv.Items.Count) and (not MoveUp)) then Exit; lv.Items.BeginUpdate; try if MoveUp then DestItem := lv.Items.Insert(Item.Index - 1) else DestItem := lv.Items.Insert(Item.Index + 2); DestItem.Assign(Item); lv.Selected := DestItem; Item.Free; finally lv.Items.EndUpdate; end; if SetFocus then lv.SetFocus; DestItem.MakeVisible(False); end; //此為調用過程,可以任意指定要移動的Item,下面是當前(Selected)Item ListViewItemMoveUpDown(ListView1, ListView1.Selected, True, True); //上移 ListViewItemMoveUpDown(ListView1, ListView1.Selected, False, True); //下移 //TListView組件使用方法 //引用CommCtrl單元 procedure TForm1.Button1Click(Sender: TObject); begin ListView_DeleteColumn(MyListView.Handle, i); //i是要刪除的列的序號,從0開始 end; //用LISTVIEW顯示表中的信息: procedure viewchange(listv: tlistview; table: tcustomadodataset; var i: integer); begin tlistview(listv).Items.BeginUpdate; {listv:listview名} try tlistview(listv).Items.Clear; with table do {table or query名} begin active := true; first; while not eof do begin listitem := tlistview(listv).Items.add; listitem.Caption := trim(table.fields[i].asstring); // listitem.ImageIndex:=8; next; end; end; finally tlistview(listv).Items.EndUpdate; end; end; //ListView使用中的一些要點。以下以一個兩列的ListView為例。 //→ 增加一行: with ListView1 do begin ListItem := Items.Add; ListItem.Caption := ' 第一列內容'; ListItem.SubItems.Add('第二列內容'); end; //→清空ListView1: ListView1.Items.Clear; //→得到當前被選中行的行的行號以及刪除當前行: for i := 0 to ListView1.Items.Count - 1 do if ListView1.Items[i].Selected then //i=ListView1.Selected.index begin ListView1.Items.Delete(i); //刪除當前選中行 end; //當然,ListView有 OnSelectItem事件,可以判斷選擇了哪行,用個全局變量把它賦值出來。 //→讀某行某列的操作: Edit1.Text := listview1.Items[i].Caption; //讀第i行第1列 Edit2.Text := listview1.Items[i].SubItems.strings[0]; //讀第i行第2列 Edit3.Text := listview1.Items[i].SubItems.strings[1]; //讀第i行第3列 //以次類推,可以用循環讀出整列。 //→ 將焦點上移一行: for i := 0 to ListView1.Items.Count - 1 do if (ListView1.Items[i].Selected) and (i > 0) then begin ListView1.SetFocus; ListView1.Items.Item[i - 1].Selected := True; end; //不過在Delphi6 中,ListView多了一個ItemIndex屬性,所以只要 ListView1.SetFocus; ListView1.ItemIndex := 3; //就能設定焦點了。 //Delphi的listview能實現交替顏色麼? procedure TForm1.ListView1CustomDrawItem( Sender: TCustomListView; Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean); var i: integer; begin i := (Sender as TListView).Items.IndexOf(Item); if odd(i) then sender.Canvas.Brush.Color := $02E0F0D7 else sender.Canvas.Brush.Color := $02F0EED7; Sender.Canvas.FillRect(Item.DisplayRect(drIcon)); end;

2010/03/13

讀書心得:蟹工船

「誒!下地獄囉!」

上面就是這本書的開場白。

前陣子這本書的內容被翻拍成電影,印象中說是「以詼諧的手法來描述資本主義社會的黑暗」。

覺得可能會很好看,於是去圖書館借。

在排隊排了很長的一段時間,總算是排到了,收到通知的當天就去拿回來看。

剛開始看的時候,就感覺內容好昏暗
看到中期,啊,怎麼這麼可憐
看到後期,機車!怎麼還不反抗!
熬到結局………自己去看吧!(眾人毆)

看完之後的感想是,真的,現在台灣的社會環境和80年前的日本,其實有越來越像的趨勢

資本家越來越來富有,而窮苦的人卻越來越窮苦…

在這本書上可以看到幾種人,以很鮮明的個性表達了現在的各種角色,比方說像是:
書裡的漁、雜工 = 現在的窮忙的現代人 = 羊、鹿…只要是草食動物就行
書裡的薦頭 = 現在的人力仲介 = 誘餌、獅子的僕人?還是動物管理員?
書裡的監督 = 現在的中階幹部 = 鬚狗
而boss呢?還是boss = 獅子

就這樣,一個活生生的食物鏈就在這本書上演了。

其中,有2/3的劇情真的讓人高興不起來,不過卻又讓你有不得不看下去的衝動。

如果,我們的生活結構不去改變,那麼,就真的如同這本書的開場白一樣:
「誒!下地獄囉!」

不過,這樣一來,可憐的就是那些中階幹部了吧!哈哈!

最近開發案子之後的心得

自上次看了Delphi Databases: Dynamic Datamodules at Runtime後,就一直在找機會將這個方式移植到自己的專案上面。

所幸最近BOSS開了新的案子,才有機會將這個方式導入到專案中。

期間遇到的事情也不少,簡單的記錄一下好了。

一、auto_ptr很好用,但出問題時會不知道為什麼發生。(這和自己的功力有關)
二、DataModule Class只做了一個,然後包裝到其它的class中,這個方式會造成很多很多重複new delete的程式碼,比較好的作法應該還是依靠IDE對datamodule的實作,這樣new/delete就會很少出現。
三、承第二點,若未來要改成n-tier的作法,datamodule會改很大,所以也不建議這樣改。
四、想到再繼續寫…

也有一些優點的啦!
一、資料存取時,DB壓力較小
二、因為採用了部分設計模式,大部分程式都靠自己的CLASS解決了,IDE FORM裡的程式碼可以很簡潔。
三、承第二點,IDE FORM專門處理自己的事件,同樣的,商業程式碼也都轉向自己的CLASS來處理,在程式修改上可以很方便的處理。
四、發現用DELPHI來寫時,速度會更快(汗)
五、更加了解DBX的運作過程
六、多玩了DATASNAP的架構
七、一樣,想到再繼續寫…(逃)

2010/03/02

TClientDataSet Run-time時期應注意的地方

主旨:為了避免已建立的VCL的屬性莫名指向NULL,建議由使用者自己使用new建立TClientDataSet。

說明:

如果不想在Design-time時期設定好TClientDataSet各項參數,可以採用Run-time設計模式。

但如果TClientDataSet是於Design-time時期就已建立,在Run-time時期,該TClientDataSet開啟後,TDataProvider會指向NULL,此時再對該TClientDataSet->Close();,就會發生ACCESS ERROR。

解決方式:
Design-time時期於form表上加入TClientDataSet時,IDE會在 __published 區自動增加TClientDataSet *Temp;
而在Rum-time時,TClientDataSet資料傳輸的主控權即交給IDE自行處理。

所以使用者要擁有較高的管理權,可採自行於程式碼中 new /delete TClientDataSet即可。

2010/3/4 更新
在Help裡查到:
TClientDataSet若是使用SetProvider指向DataSetProvider(Run-time),則TClientDataSet Close()再開前需要再使用SetProvider指向DataSetProvider





動態建立 ClientDataSet 的範例可參考:
ADO and ClientDataSet

2010/03/01

No BOOLEAN field in Firebird?

No BOOLEAN field in Firebird?


There is no built-in boolean field, but you have several options:

1. use char(1)
2. use smallint
3. use domains

Domains are probably the best solution. You can create domain like this:


CREATE DOMAIN BOOLEAN
AS SMALLINT
CHECK (value is null or value in (0, 1));


Later in table definition you can refer to it as a regular datatype.


CREATE TABLE t1
(
C1 VARCHAR(10),
B1 BOOLEAN,
B2 BOOLEAN NOT NULL,
...
);


If you use a connectivity library like OleDB under .Net, you can override the OleDB provider's GetSchema method, so the DataTables you get from queries have native .Net booleans.

2010/02/26

ListView,看完頭都昏了的行列…到底是直的還是橫的呀?

TListItem *lst
AnsiString a,b,c;
lst=ListView1->Items->Item[i]; //第i列(row)

a=lst->Caption; //第一行(column)
b=lst->SubItem->String[0]; //第二行(column)
c=lst->SubItem->String[1]; //第三行(column)

看原文好像有比較清楚的樣子
請參閱:橫行直列,橫列直行?

2010/02/25

BCB6的DBX沒提供完整的column_alias功能?!

BCB6內的DBX並未提供FIREBIRD的DRIVER,所以只好使用InterBase的driver來將就一些。

而在一些SQL-SELECT的應用上,難免會用到「Column_alias」功能。

在alias連續時,在操作上是沒有問題的。比方說像是:

SELECT field_name AS Column_alias FROM table_name
以上的寫法是沒有問題的。

但是如果中間需要空格,像是:
SELECT field_name AS "Column alias" FROM table_name
這樣的寫法在Firebird所提供的 isql 操作時沒有問題,不過在BCB6執行時卻會產生語法錯誤的情形。

啊,要怎麼解決這個問題呢?

看起來是沒有(暈)

不過倒是有迴避的方法:
在DataSet開啟後,將Fields的「DisplayLabel」改名掉就可以了。

不是很方便,但卻可以解決掉DBX內的 大BUG 疑似小問題吧。(笑)

2010/02/24

從「艋舺」來看校園霸凌

在看了最近期待指數很高的電影--「艋舺」之後,家人的感覺是:很像在看台灣版的古惑仔。

但其實我覺得結局還蠻好的,至少不會讓人認為走入黑道是很「光榮」的事情。(這就叫自我感覺良好嗎?)

踏入黑道就像吸毒一樣,一但染上了,就脫不了身了。

但是,黑道是怎麼吸收學生的呢?從劇情的舖陳來看,大部份的情況會是:首先會有黑道的兒子(很跳)、被欺負的可憐蟲,再來就是從中找出合適的對象,最後再吸收,變黑道,然後無盡的循環。

報應不止,屢試不爽。

而什麼是「合適的對象」?就是頭腦好、有膽識的、有氣魄的,大概就是合格的對象了。(所以我才會坐在這邊分析)

但這些合適的對象都有一個共同的特色,就是「被欺負的可憐蟲」。這種人最好騙,只需要保護他們,他們就會死心踏地的跟隨心中的「保衛者」。

「以暴制暴」才是社會的真理嗎?

我們都知道,社會中有警察,校園中有老師、教官,家裡有家長,難道這些都沒有辦法對「被欺負的可憐蟲」有所幫助嗎?

以自身的經歷來看:很抱歉,完全一點幫助也沒有。

師道淪喪現在已經不是新聞了,現在的老師動輒得咎,動不動就會到學校來個「興師問罪」,學校擔心會影響校譽,導致學生入學率,變成了「學生才是老闆」的情形。

警察對校園霸凌事件有解決的能力嗎?從現行的校園自制法來看,警察不是不能進入校園,但需經過繁雜的程序以及學校的同意才能進入。演變成警察權被銷弱的情況。

其實想到的還有很多,有時間再從校園霸凌衍生的同儕壓力、教化、教育、盲點、廢除死刑等議題研討吧。

2010/02/22

拜個晚年吧

hihi
在還沒過元宵節前都還算過年的啦!
哈哈!

在這邊向有到敝站觀光的網友們拜個晚年囉!

2010/02/11

Delphi / C++ Builder's RichEdit行號取得方式

Delphi / C++ Builder's RichEdit行號取得方式
原文內容:Get the line number from a RichEdit

沒錯,TRichEdit就是沒這個方法 造物者boland忘了生給它了
不過我們可以利用Win事件訊息來取得RichEdit當時游標所在的行號。
(以下RichEdit以REdit取代)

REdit.Perform(EM_LINEFROMCHAR, REdit, SelStart,0);

它的回傳值就是行號(型別就是INT)。
另外,它會順便帶Win事件訊息「EM_CHARFROMPOS」,藉此回傳這個游標在全畫面中的位置(座標)。
詳情請參閱MSDN。

注意,因這個函式非常的慢,所以不建議在大量迴圈內使用它。

2010/02/10

使用Delphi體驗物件設計模式

最近看了「參悟物件設計模式-使用Delphi」一書後,一直很想找時間來練習IDE上的設計模式玩法。

剛好最近開了個新案子,於是就興高彩烈的著手設計。

但已經被IDE慣壞的我,真的很不能適應一堆抽象物件的處理方式。

果然還是得多加練習呀!

2010/02/05

Database's foreign key!

The foreign key is very importent in db designing.

Recently test my firebird db system, I used IB Expert create a table and set up some fields, type and primary key.

After I set Constraints->Foreign keys-> Set default rule->On Field, FK Table, FK Field etc.

"Update Rule" and "Delete Rule"is very interesting.

You can set: NO ACTION, CASCADE, SET NULL and SET DEFAULT. It not like MySQL after setup rule but can not used. Is very nice!

噁心的一餐…

好久沒吃羊肉爐了,想說今天加班,也犒賞自己一下。

於是下了班就到離我家最近的藥膳羊肉去大快朵飴一番。

雖然整個店面破破舊舊的(車站旁的鐵皮屋,品質當然就…)
點了碗藥膳羊肉+炒飯後,就開心地吃了起來,就在快結束的時候…

--怎麼會有胯下一星期沒洗的那個味道跑出來--

心裡還在納悶的時候…

X!味道還越來越重!

會是羊肉的味道嗎…?不,不是!

真是越吃越噁心…

下次不會再去那家吃了啦!

咦?我好像聽到有人說這是「男人味」?

嗯…又迷惘了

最近在思考一些關於設計模式程式設計的方向,發現要看的東西還真是不少

UML、DB、物件化…等好多好多

除了這些以外,還有Perl、Nrcomm等好多VCL元件說明書等著我去看,真是要命

時間可以說是越來越不夠用啦!

2010/01/30

讀書心得:C++ Builder資料庫程式設計-人事薪資系統實作


<陪我走過最最艱辛的加班時光的工具書>

這本書入手也快4年了,對這本書真的有深厚的感情,其實,到現在,它還是我常常拿在手中的一本 武器 工具書。

其實,在我剛踏入程式設計領域時,我真的完全有看沒有懂,但是看著作者講得 天花亂醉 如夢似幻,心裡也很想享受駕御DBExpress的快感(謎之音:到底誰會想要這種快感呀……)

後來,稍微懂了資料庫程式之後,再回來看這本書,真的,看懂一些了,也大概知道作者所要表達的是什麼了。



一心手癢難耐的我,就開始對手上的專案開始塗改了!(哥哥有練過,小朋友要學…也是可以的啦!)

從BDE->BDE / DBX共存,到純DBX,中間花了數不清的加班時間,有很多BDE很方便的,但DBX卻要很迂迴才能辦到的處理方法,比方說:像Setkey就是一個例子,但是DBX也有很優的MYBASE可以使用(TClientDataSet應用),比起使用BDE + PARADOX來說,無疑是方便上許多 BDE雖然也可以這樣做,但我也是在使用DBX之後才知道BDE也可以這樣玩。

做了前面六個章節後,發現專案已經完成七、八成,原來我的專案還不夠花俏呀!哈哈!

<被我凌虐到開始掉頁的可憐書>

萬變不離其宗,做到這裡才發現其實DBX與BDE並沒有差那麼多,與VB5、6的DBGrid->DataGrid的 暴力 和平演變,BDE->DBX比較起來還是順暢多了。

也多虧有看這本書,現在才會開始利用Firebird embedded資料庫來開發程式,比起使用BDE+ODBC封裝程式,DBX及麻吉的InterBase姐妹品似乎有更優的相容性,在封裝給客戶時也很直接,真是令人意外的發現呀!

最後,再來說說這本書的缺點吧:
一、錯字很多
二、有些地方排版錯誤
三、裝訂品質不是太好
四、貼到Delphi的程式碼

2010/01/25

家裡有很多「老兵」-- 其一

其實小時候不學無術,長大後才知道自己買了多少怪「雞絲」

為了一圓自己當漫畫家的夢想,在n年前買了台Scanner--AGFA SNAPSCAN 1212P
是「P」喲!走的是LPT1介面的!不是USB!!!
<現在還在服役的老兵:AGFA SNAPSCAN 1212 P>

還…還真是老舊呀!但是呢,我家的電腦也好不到哪裡去--DURON 1.3G的舊舊電腦
不過還是裝了WINXP,怎麼樣也無法與這台古老級(還不到作古級)的SCANNER連線,原來是它的DRIVER不支援WINXP啦!哈哈,拜GOOGLE大神之賜,很快地找到了安裝它的辦法。花了不少時間來安裝,結果總算是能動了!

不過呀,好慢呀,老兄,你也真的太慢了吧!

話雖如此,我的畫作卻一張也沒掃進去過……(汗)

2010/01/21

VB6的DBGrid與DataGrid

最近接到了一個修改VB6專案的小程式,發現裡面有DBGrid元件,在開始讀這專案的時候,真是費了不少時間,想說,要痛就痛一次吧!

於是就開始進行替換工作,原本想說換好之後,在改成.NET2005應該會比較不痛一點,但沒想到DBGrid真是做的太好了,很多程式也要一併修改掉!

再者,這專案也會用到MSCOMM元件,VB.NET2005沒這玩樣!

花了不少時間在DEBUG工作…算了,還是選擇少重灌VB6好了 XD

2010/01/19

C++ Builder 全系列 我猜 無法安裝TPerlRegEx

最近在嚐試安裝TPerlRegEx(2008年的Final版)元件在C++ Builder上,安裝平台是:BCB6, CB2010,但卻都會發生異常的錯誤訊息。

可能針對的是Delphi版設計的吧,目前還找不到可以安裝在C++ Builder上的辦法
在Delphi社區已經被研究到爛的東西,想不到在cb上卻無法順利執行,真是嘔啊!

真的要找時間好好來研究Boost::Regex了。反正也是走正統Perl語法,哈!

2010/01/18

BCB6 + Boost::Regex

老東西還是能玩出新花樣吧
最近在K字串比對的花招,發現原來 C++ Builder 2010 有提供Boost類組來處理文字技術
那麼,使用Regex應該不是什麼難事吧

目前應用在delphi產品中很出名的TPerlRegex,新的版本(2008年出的)並不能安裝在 C++ Builder 2010上,當然,也不能安裝在BCB6囉!

目前唯一能用的是TPerlRegex 2005年推出的舊版本,雖然我不知道這其中多了什麼東西,但能用新的當然是越新越好啦!哈哈!

因為 C++ Builder 2010的Boost安裝程式不支援 BCB6 安裝(廢話),所以只能到 Boost 的官方網站上下載最新的版本。

咦?有1.41版耶!這足足比 CB2010 所提供的1.35足足多了近「0.1」的版次,想必功能應該更齊全吧!(其實根本用不到這麼多,只是簡單的文字比對而已……)

在 BCB6 上編譯時,發現沒問題!安裝也OK。但在include boost後測試demo,卻現在 BCB6 找不到1.40的檔案!還真是奇怪的問題,可能是1.41還在測試階段的關係吧,沒把安裝程式包好。

於是改用1.40版本,果然一切正常,花了一個星期的時間研究「如何安裝」…終於可以開始實測囉!!!

2010/01/14

這…應該是與2010的計畫無關吧

好…好吧
我承認我又開始走偏路了! XD

最近因為公司新開案的內容,有用到關於字串的驗証
字數有多有少,中間還有一槓…

一想就覺得是件需要用到大量程式碼的東西…

嗯…何不使用正規表示式呢?

於是又把精力花在正規表式上面了……

我想,最近研究這個的時間應該會比我寫程式碼的時間還要多吧,哈哈!

2010/01/11

果然,這真的代表小時候國中地理歷史不好…

最近開始準備導遊領隊考試

看了很多參考資料後…
來做做模擬考吧!

結果…

47.5...........

真是嚴重的打擊呀!

看來,國中史地真的要好好研讀了呀!!!

2010/01/07

SQL-92: CONSTRAINT 用法

這兩天在找Table的正規化方法找了老半天,所幸和Carey大聊過之後,有了初步的認知:

原來複合Key也是可以當作Table唯一的主Key呀!

於是就開始尋找複合Key的建立方式,後來在CONSTRAINT SQL運用中找到很漂亮的介紹。

好像是與Oracle有關,於是又在國外找到了與Firebird相關的SQL內容:
FireBird Database Constraints

以下是節錄部分的內容:
CREATE TABLE DAILY_PRODUCT_SALES (
DATE_OF_SALE DATE NOT NULL,
PRODUCT_ID INTEGER NOT NULL,
UNITS_SOLD INTEGER NOT NULL CHECK (UNITS_SOLD >= 0),
CONSTRAINT UNIQUE_DAILY_SALES
PRIMARY KEY (DATE_OF_SALE, PRODUCT_ID)
);

嗯嗯,看起來與Oracle差不多,或許這也是Ansi SQL-92的標準語法也說不定。

2010/01/06

這幾天看了終於開始看AIR了,不過…(續篇)

續上回AIR前六集的觀看心得後,又繼續把後面的七集給看完了。

前面感覺像是在鋪陳1000年前的事情,把所有轉生人物都介紹一次之後才開始正式進入1000年前的劇情。但…看完之後我還是沒找到摧淚因子……感覺有很多想交待卻沒敘述的劇情(按維基百科的說明是濃縮了很多劇情)。可能是 因為我不懂日文 遊戲沒有實際玩完吧。

但聲優真的很棒!
40歲可以演出14歲的聲音!真是無懈可擊!

完全著迷了呀!(倒)

題外話:如果日語教學錄影帶的老師聲音也是這麼可愛的話,我想學日語的人應該會爆增吧,哈哈!

DBX framework 初探

DBX 框架在官方手冊裡有句話引起我的注意: Currently, using a TDBXValue is the fastest way to pass a parameter, because these are the internal objects used...