2008年1月17日 星期四

Append a string to CEdit

最近為了某些事,自己動手做了簡單的 GUI, 我以前從來沒有碰過 MFC 的,學生時候也只用 BCB 拉過簡單的 GUI。由於以前沒碰過,所以連些最簡單的小東西我也可能不知道藏在哪邊,自己找不到時就要問 GUI team 的同事。
不過現在碰到一個小問題,很基本的小問題,竟然問了半天都沒有好的答案。我只是要在 multi line 的 CEdit 後面加一行字串,不論是 google 還是問人,都只能得到爛爛的方法,沒辦法像 CListBox 或 BCB 的 TMemo 一樣,用一個 AddString( ) 就解決,所幸最後還是找到了堪用的解法(不想看過程的人請直接跳到最後面)。
那為何不用 CListBox? 因為 CListBox 不能選取/copy/paste。

第一版:

就是先 GetWindowText( ) 到 buffer中,把字串字自往 buffer 後面加上去,再 SetWindowText(buffer) 回去。真是爛到不行的點子,也是最多人提出的解決方案。我明明只是要加字串到尾端,竟然還要先讀出全部的舊字串再寫回,又麻煩又影響效率,還得考慮配置 buffer 的相關問題。

第二版:預先配置一個 buffer, 把要 append 的字串先加入 buffer, 再把整個 buffer 透過 SetWindowText( ) 寫入 CEdit。這個方法其實跟第一個方法一樣,換湯不換藥,只是把工作換個地方做而已,而且從軟體工程的角度來看,其實更糟,因為這個 buffer 必需配置在 function 以外的地方,可能是某個 global 變數或是某個 class member, 若要放在這個 Append function 中,就得做成 static,那在 multi thread 時又會出問題!

第三版:網路上找到的方法,我把它包成 function:
inline void AppendStringToEdit(const string &str, CEdit &edit)
{
int length = edit.GetWindowTextLength();
edit.SetSel(length, length);
edit.ReplaceSel(str.c_str());
}
道理很簡單,就是先選取該 edit 中最後的部分,再將它取代,而這個被選取的部分其實是空的,因此造成 append 的效果。這雖然不太直接,但看來應該可行,可惜事與願違,它會把我要加的字串加在第一行的尾端,而非最後一行。

第四版:自己亂試試出來的
inline void AppendStringToEdit(const string &str, CEdit &edit)
{
edit.SetSel(-1, -1);
edit.ReplaceSel(str.c_str());
}

這個是第三版的改良版,會選取游標所在之處,而預設情況下,游標會在文字的最尾端,所以可以達到我想要的效果,這版終於做到我要的效果了!! 多數人應該到此就會打住了吧但我還是不滿意,因為只要使用者有動到游標(例如他想選取一部分 copy 起來),插入的位置就不在尾端,於是文字就亂掉了,因此有下一版的產生。

第五版:不會被游標干擾的版本
inline void AppendStringToEdit(const string &str, CEdit &edit)
{
int nBegin = edit.LineIndex(edit.GetLineCount() - 1);
int nEnd = nBegin + edit.LineLength(nBegin);
edit.SetSel(nEnd, nEnd);
edit.ReplaceSel(str.c_str());
}

這版會先取出最後一行( GetLineCount( ) -1 )所在的位置,然後選取該行的行末,再做取代工作,這樣就不會被使用者的游標給干擾了,太好了 :)
不過當使用者選取了某個範圍後,只要我一加新字串進去,他的選取範圍就會不見,這實在有點惱人,所以就有下一版的出現,這個改進還蠻理所當然的。

第六版:不會干擾游標的版本
inline void AppendStringToEdit(const string &str, CEdit &edit)
{
int nOrigBegin, nOrigEnd;
edit.GetSel(nOrigBegin, nOrigEnd);
int nBegin = edit.LineIndex(edit.GetLineCount() - 1);
int nEnd = nBegin + edit.LineLength(nBegin);
edit.SetSel(nEnd, nEnd);
edit.ReplaceSel(str.c_str());
edit.SetSel(nOrigBegin, nOrigEnd);
}

這版只多做一件事,就是把原先的選取範圍存下來,做完上一版事情後,再把原先的選取範圍給選回去. 就是先 GetSel( ),做完事後再 SetSel( )。這樣看起來舒服、自然多了。


CEdit 的 Append 改版到此暫時告一段落,不過若我發現還有改善空間還是會再改進的。

心得:MFC 果然是爛東西。

2008年1月14日 星期一

這樣國民黨才不會賣台




2008 立委選舉出爐,國民黨可控制的席次高達四分之三,接下來的總統大選,馬英九勝出的機率非常的高,許多本土派的支持者都很擔心國民黨、統派會賣台,與中國談判、統一。其實我覺得事情正好相反,國民黨大勝,他們才不會賣台!!
大家回想一下,連、宋也是選輸才賣台的嗎? 選輸才去北京跟胡錦濤等人眉來眼去、聯共制台獨的啊! 其實這是人的劣根性,鬥輸了之後,為了自身利益,同室反目,甚至不惜與敵人聯手以求去翻身的機會。歷史上有太多這樣的例子:

  • 2000 年總統大選前,無法獲得黨內提名,宋楚瑜脫離國民黨參選、許信良脫離民進黨黨參選。
  • 2000 年民進黨勝選後,沒分到利益的人或投奔敵營,或天天上2100,例如胡忠信。
  • 比胡忠信多撐了幾年,最後揚憲宏也2100了。
  • 連戰、宋楚瑜:選輸兩次後,連掩飾都懶得掩飾了,不搞亂局勢哪有翻盤的機會?
  • 時間比較久的,大家最耳熟能詳的就是吳三桂了,打不贏李自成,直接就引清兵入關了。
  • ......
好了,回來看現在的國民黨,他們若拿下執政權,對國會又掌握絕對多數,那麼自己吃台灣就好了,幹嘛跟阿共仔分利益? 所以大家可以放心,國民黨選贏了不會賣台,選輸了才會!
至於獨大的國民黨,是否讓台灣民主大倒退? 其實也不用那麼悲觀,雖然國民黨拿下絕對多數,但組織一大,內部的矛盾必隨之而來,利益分配永遠不能讓每個人滿意,分裂只是早晚的事。(不然新黨、親民黨、台聯是怎麼來的?) 不妨想像一下五月內閣就職時,林郁芳發現自己沒當上國防部長的表情。

對於這個獨大的政黨,我們甚至可以反過來利用它! 即然可以一手主導修法、修憲了,那麼很多事情就沒有藉口推託了。舉個例子,之前國民黨一直主張我國應該是偏向內閣制的雙首長制,那麼趁現在把它弄清楚吧,不論要改成內閣制還是總統制我都沒意見,最重要的是要有個明確方向,不要像現在這樣曖昧不明的,造成一大堆的爭議。
陰謀一點的也可以想像一下,改成內閣制等於是削馬英九的權,他一定面有難色,改成總統制的話,要那四分之三的委員揮刀自宮嗎? 這可怎麼辦啊....

當前政局,民進黨該做的是防止國民黨用這絕對的權力對台灣造成巨大而不可逆的傷害,運用清晰的說理能力來說服民眾、制造輿論壓力來防止這些事情的發生(例如僅照顧少數人錢坑法案)。
其實從另一個角度來看,本土派已對統派造成巨大而不可逆的傷害,這個傷害就是大多數台灣人都已認同台灣是主權獨立國家,想要與中共統一變的基乎是不可能的事。這個本土化的概念是如此成功深植人心,許多人民甚至不相信國民黨會賣台,或不信國民黨有能力賣台(因為人民會反對),從這個角度來看,其實本土派的成果是深遠而豐碩的!

對於台灣的未來,我們可以非常的樂觀!