討論區快速選單
知識庫快速選單
程式設計俱樂部Facebook粉絲團 掌握Salesforce雲端管理秘訣 政府補助!學嵌入式+物聯網
[ 回上頁 ] [ 討論區發言規則 ]
MFC 提供的 Ribbon 可以用嗎?
更改我的閱讀文章字型大小
作者 : sunyear(coco) VC++卓越專家C++頂尖高手貼文超過2000則
[ 貼文 2421 | 人氣 1485 | 評價 6060 | 評價/貼文 2.5 | 送出評價 5 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/6/20 上午 11:52:41
個人在評估使用VC2010開發ribbon介面的程式,大概接近尾聲。
個人的看法是:可以用,但沒想像中好用,原因:
1.說明資料嚴重不足。
 可能是因為提供的功能是較新的介面,資料上還未能充分提供。
 目前較唯一可行的替代方式是直接去看MSOffice2007Demo範例程式。
2.ribbon的編輯器尚有不少bug,常常被它搞得火冒三丈。
3.並不遵循誰建立的物件誰負責銷毁。雖然很多時候也不得不然。但總覺得
 MFC ribbon 元件的建立和銷毁是令人困惑的。
 看起來是,你動態建立了
 一個ribbon元件,然後加進了ribbon bar後就可以不管它了。當ribbon bar
 生命期結束後,就會自動銷毁你動態建立的那個元件。那如果,加入的元件
 不是動比建立的呢?會被delete而發生exception嗎?元件如果由別的模組
 所new出來的,又會怎樣?很多的疑問,MSDN並沒有交待...
4.有許多control的細微控制,並不週全。這在撰寫商業化程式會是致命的。
 例如 spin edit 雖然提供了範圍值的屬性,使用者直接輸入數值時卻沒有
 錯誤檢查。甚至輸入一個非數值的字元,它也接受。
 追踨了MSOffice2007Demo的做法,它自製了一個CMFCRibbonNumEditCtrl
  繼承自 CMFCRibbonRichEditCtrlspin。用類似於傳統subclassing的方法。
 (因為沒有提供像是DDX的替換control方法,所以實現起來複雜得多)
 CMFCRibbonNumEditCtrl就可以檢查使用者輸入的字元和其它細微的控製。
 這也OK,但MSDN上說所有的"ribbon control class都是MFC內部的元件,
 不應該使用在application的程式碼上"。也完全沒有說明文件(不給你用,當然不給資料)
 乖乖,這就累了!不用?微軟自己的MSOffice2007Demo不也用了嗎!顯然不用的話,
 以目前MFC 提供的 ribbon只能在家玩玩,上不了台面。那就用吧!(反正微軟自己的application
 都用了,那有只許州官放火不許百姓點燈的道理)。問題是,沒有文件說明,用起來可是
 超級辛苦,得要有心裡準備。

結論:微軟號稱提供了像office ribbon的介面了,但看起來比較像是拿出來炫耀而已,很多重點是
   多所保留。真的想用,你得憑自己的本事去挖!
作者 : daniel(冷眼)討論區板主 VC++優秀好手遊戲程式設計優秀好手DirectX優秀好手C++優秀好手貼文超過1000則人氣指數超過70000點
[ 貼文 1564 | 人氣 84169 | 評價 6990 | 評價/貼文 4.47 | 送出評價 15 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/6/20 下午 12:50:40
其實你應該從bcg pro下手..
因為他有比較完整的源碼

不過Ribbon 跟 tabber + controlbar view
有什麼差異嗎 = =||

作者 : sunyear(coco) VC++卓越專家C++頂尖高手貼文超過2000則
[ 貼文 2421 | 人氣 1485 | 評價 6060 | 評價/貼文 2.5 | 送出評價 5 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/6/20 下午 04:34:19
>其實你應該從bcg pro下手..
>因為他有比較完整的源碼
我知道有第三方的ribbon支援。bcg是一個,codejock xtreme也有。
用第三方的開發套件,以前用很多,但我打算日後儘量少用(不得已時才用)。
原因是,第三方套件常常不容易隨VS版本升級,這讓我吃了不少苦頭。
(這是我現在大部份的軟件都還在用VC6的原因)
既然評估VS2010,當然希望儘量不要重蹈覆轍。
當然,也是看到已前需要第三方支援的東西,VS已經開始支援,這也是升級VS2010
的最大動力。
MFC ribbon和其它MFC類別一樣是帶有源碼的,但源碼是一回事,說明文件是一回事。
不可能沒文件,凡事都自己追蹤鴻碼來尋求解答。
事實上MFC ribbon就是BCG改過來的(基本上那些元件的類別只是從CBCGxxx改成CMFCxxx而已)
雖然,ribbon是微軟先行在自家office產品推出的介面,但要整合到MFC卻不容易。
所以微軟走捷徑,買下BCG,改個招牌就成了MFC ribbon了^^
為了將來升級的考量,你還會建議我用BCG嗎?

>不過Ribbon 跟 tabber + controlbar view
>有什麼差異嗎 = =||
Ribbon是一種更炫的tool bar(應該說是另類的system/menu/tool bar);
tabber + controlbar view算是更炫的view window。
一個改良上半部,一個改良下半部^^
作者 : ccl0504(手動程式產生器) 貼文超過200則
[ 貼文 450 | 人氣 211 | 評價 930 | 評價/貼文 2.07 | 送出評價 2 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/7/7 上午 08:59:54

>>其實你應該從bcg pro下手..
>>因為他有比較完整的源碼
>我知道有第三方的ribbon支援。bcg是一個,codejock xtreme也有。
>用第三方的開發套件,以前用很多,但我打算日後儘量少用(不得已時才用)。
>原因是,第三方套件常常不容易隨VS版本升級,這讓我吃了不少苦頭。
>(這是我現在大部份的軟件都還在用VC6的原因)
從 bcg 下手的原因, 是因為 MS ribbon 的部分是以前從 bcg 拿過來的
看 bcg 會比較容易懂

http://blogs.msdn.com/b/vcblog/archive/2008/04/07/mfc-update-powered-by-bcgsoft.aspx

作者 : henrytso(CodeWarrior) VC++優秀好手貼文超過200則
[ 貼文 243 | 人氣 4166 | 評價 1790 | 評價/貼文 7.37 | 送出評價 6 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/7/23 下午 03:19:16
個人用 BCGPro 已經用了3年, 對於每次 Visual Studio 的改版, BCG 都會在 Visual Studio Beta 前就有支援, 這次 Visual Studio 2012 也是一樣, 感覺支援不是問題.

之前因為某些需要, 特別用 BCGPro 的 Ribbon 來做 U/I , 過人覺得BCGPro 的 Ribbon 還算好用.
作者 : sunyear(coco) VC++卓越專家C++頂尖高手貼文超過2000則
[ 貼文 2421 | 人氣 1485 | 評價 6060 | 評價/貼文 2.5 | 送出評價 5 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/8/20 下午 03:09:16
>個人用 BCGPro 已經用了3年, 對於每次 Visual Studio 的改版, BCG 都會在 Visual Studio Beta 前就有支援,
>這次 Visual Studio 2012 也是一樣, 感覺支援不是問題.
 Hello CodeWarrior.
你可以幫忙試一下,BCG是否有這個問題嗎?
ribbon有一個叫Minimize ribbon的功能,中文名稱叫"最小化功能區"。
它在平時不用ribbon時,整個ribbon bar就只會剩下類別列那一行。
等使用者點取類別(相當於點選menu)時,整個帶狀的ribbon就會自動出現。(有點類似自動隱藏)
問題是這樣的,我在ribbon的panel加上一個slide control,在功能區沒有最小化時,沒有問題。
但當功能區在最小化時,那個slide control是可以拉動它,但event handle去抓slider的position,
得到滑塊位置都是舊值。當帶狀ribbon恢復隱藏,然後再度被使用而現時,那個滑塊就恢復到舊位置去。
這邊有一個可以試出問題的project,可以下載測試( 使用VS2010):
http://sdrv.ms/R8SIGv
另外我也做了一個,執行桯式時錄下的avi檔可以看:
http://sdrv.ms/SEKQd5
作者 : ccl0504(手動程式產生器) 貼文超過200則
[ 貼文 450 | 人氣 211 | 評價 930 | 評價/貼文 2.07 | 送出評價 2 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/8/21 下午 04:12:51

reason :
http://blog.csdn.net/cmaxpath/article/details/7256228

fix :
http://sdrv.ms/NCBIJj

作者 : sunyear(coco) VC++卓越專家C++頂尖高手貼文超過2000則
[ 貼文 2421 | 人氣 1485 | 評價 6060 | 評價/貼文 2.5 | 送出評價 5 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/8/21 下午 10:40:57
>reason :
>http://blog.csdn.net/cmaxpath/article/details/7256228
>fix :
>http://sdrv.ms/NCBIJj
to:ccl0504
謝謝你的資訊。
reason那一篇我看了一下,應該只有一部份是對的(但也看是很重要的一部份)。
至於他貼的解決方法,看起來不可行。
ribbon的原始碼我也追蹤過,
重點在於slider的複本OnLButtonUp()時,沒有更新到正本,所以正本的position沒有更新。
繼承CMFCRibbonSlider然後改寫OnLButtonUp(),沒有用。雖然OnLButtonUp()是虛擬成員,
但在製造複本時,用的還是CMFCRibbonSlider不是繼承CMFCRibbonSlider的新類別。
fix那一個project,是用我貼的顯示CMFCRibbonSlider的範例改寫的。看這貼文的最後篇:
http://social.msdn.microsoft.com/Forums/zh-TW/vcmfcatl/thread/9fdee956-56a5-4ae5-8081-4e6962a2a961
這是你改寫的嗎,看起來作者對ribbon道行頗深,我很有興趣。它連CMFCRibbonBar都改寫了,
主要也是為了製造複本時能使用繼承CMFCRibbonSlider的新類別。
我現在的電腦沒VS可以試,明天再玩它看看。連複本的製造都改寫了,至少應該是可行的方向,
之前我只想到複本不是新類別就止住了,沒想到要去改那麼大^^
(以我對ribbon的接觸時間只能想到'點',無法全面的思考)
另外一提,fix那裡面OnLButtonUp()的作法有點風險,因為經由CopyFrom傳過來的source,之後並不一定存在,
所以OnLButtonUp()裡面不能不管三七二十一的操作它。不過這應該已是小問題了。

最後忍不住再對微軟抱怨,ribbon好歹也面世好多年了,怎麼還會有這麼大的major bug?
我很好奇,如果BCG沒有這個bug,那一定是俄老賣給微軟時留了一手 :D
作者 : ccl0504(手動程式產生器) 貼文超過200則
[ 貼文 450 | 人氣 211 | 評價 930 | 評價/貼文 2.07 | 送出評價 2 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/8/22 上午 12:36:05
>fix那一個project,是用我貼的顯示CMFCRibbonSlider的範例改寫的。看這貼文的最後篇:
>http://social.msdn.microsoft.com/Forums/zh-TW/vcmfcatl/thread/9fdee956-56a5-4ae5-8081-4e6962a2a961
>這是你改寫的嗎,看起來作者對ribbon道行頗深,我很有興趣。它連CMFCRibbonBar都改寫了,
msdn 那篇是兩個小時前才發的, 剛剛還沒看過
我是照 reason 那篇貼文, 只是後來他是 hard code 建立 CMFCRibbonSliderUG, 所以我又改了一點

>繼承CMFCRibbonSlider然後改寫OnLButtonUp(),沒有用。雖然OnLButtonUp()是虛擬成員,
>但在製造複本時,用的還是CMFCRibbonSlider不是繼承CMFCRibbonSlider的新類別。
假如要 OnLButtonUp 有用, 就需要修改 CMFCRibbonConstructor::CreateElement
另外 Ribbon 是由 LoadFromResource 載入, 所以也修改了 CMyMFCRibbonBar

>主要也是為了製造複本時能使用繼承CMFCRibbonSlider的新類別。
>我現在的電腦沒VS可以試,明天再玩它看看。連複本的製造都改寫了,至少應該是可行的方向,
>之前我只想到複本不是新類別就止住了,沒想到要去改那麼大^^
>(以我對ribbon的接觸時間只能想到'點',無法全面的思考)
假如你照 msdn 上面的改法, 應該會重複很多 code (跟貼文者講的一樣, it creates ripple cascading effect)

>另外一提,fix那裡面OnLButtonUp()的作法有點風險,因為經由CopyFrom傳過來的source,之後並不一定存在,
>所以OnLButtonUp()裡面不能不管三七二十一的操作它。不過這應該已是小問題了。
自己的第一個 Ribbon source 會等於 NULL
縮小後的 Ribbon CopyFrom 的 source 就會是自己的第一個, you can trace

>最後忍不住再對微軟抱怨,ribbon好歹也面世好多年了,怎麼還會有這麼大的major bug?
>我很好奇,如果BCG沒有這個bug,那一定是俄老賣給微軟時留了一手 :D
BCGPro 裡面有 demo, 不過沒測讀出來的數字, 只有 UI
所以才沒發現有這個 bug ?

作者 : sunyear(coco) VC++卓越專家C++頂尖高手貼文超過2000則
[ 貼文 2421 | 人氣 1485 | 評價 6060 | 評價/貼文 2.5 | 送出評價 5 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/8/22 下午 05:48:25
Hi ccl0504,
你修改的程式我今天試了,可以工作。算是解了心頭大患^^
不過,我還是要認真思考日後還敢不敢用Ribbon介面 :(
>自己的第一個 Ribbon source 會等於 NULL
>縮小後的 Ribbon CopyFrom 的 source 就會是自己的第一個, you can trace
這個我知道,我的意思是來源被複製可能不是只有ribbon panel 從隱藏到彈出。
被複製的來源也可能消失(例如來源也一樣只是本尊的複製品)。
MS對複製通用介面定義是:
clone->複製自己到它方;CopyFrom->複製它方給自己。
有此需求均可呼叫,不限使用範圍。
另一個風險是,可能有幾個control 俱有相同的ID,在Control item的規則它們應一視同仁。
所以,要把複製品的position存回的不是只有來源,而是ribbon root下俱有該ID的所有control。

另外,有一些補充你的程式不週全的地方,我有貼在MSDN的英文論壇上,我想這裡或許也有人需要,
就把它也貼在這裡,提供大家參考:
1.
如前面所提,把新的position存回CopyFrom所存的來源物件並不安全。
所我改了CMFCRibbonSliderUG::OnLButtonUp如下:
void CMFCRibbonSliderUG::OnLButtonUp(CPoint point)
{
ASSERT_VALID(this);
CMFCRibbonBaseElement::OnLButtonUp(point);
if (m_nPressed == m_nHighlighted && !IsDisabled())
{
switch(m_nPressed)
{
case
nZoomInIndex:
SetPos(m_nPos + m_nZoomIncrement);
break;
case
nZoomOutIndex:
SetPos(m_nPos - m_nZoomIncrement);
break;
default:
SetPos(GetPosFromPoint(point.x));
break;
}
//Sunyear: Find out all buttons has same ID in the top level ribbon bar
CMFCRibbonBar* pRibbonBar = GetTopLevelRibbonBar();
if (pRibbonBar != NULL)
{
ASSERT_VALID(pRibbonBar);

CArray<CMFCRibbonBaseElement*, CMFCRibbonBaseElement*> arButtons;
pRibbonBar->GetElementsByID(m_nID, arButtons);
for (int i = 0; i < arButtons.GetSize(); i++)
{
CMFCRibbonSliderUG* pOther = DYNAMIC_DOWNCAST(CMFCRibbonSliderUG, arButtons [i]);

if (pOther != NULL && pOther != this)
{
ASSERT_VALID(pOther);
pOther->SetPos(GetPos());
}
}
}
//
NotifyCommand();

}
}

2.
因為OnLButtonUp 自行搜尋ribbon root下目標ID的control並更新了它們的position,所以CopyFrom的儲存source指標
已經不需要。
3.
需要修改的不是只有 OnLButtonUp.
所有呼叫NotifyCommand的成員函式都需要類似的修改。
例如 OnMouseMove, OnautoRepeat
所以 1.的"Find out all buttons has same ID in the top level ribbon bar"這段程式,獨立出成一個函式或許是比較好的做法。
4.
 有關你提到的m_nZoomIncrement,我覺得不是很重要(相較於position)
如果吹毛求庛的話,那麼也要考慮複本的m_nZoomIncrement被修改的話要不要存回本尊(如同position)。
作者 : sunyear(coco) VC++卓越專家C++頂尖高手貼文超過2000則
[ 貼文 2421 | 人氣 1485 | 評價 6060 | 評價/貼文 2.5 | 送出評價 5 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/8/23 下午 01:07:38
我惡夢還沒結束:(
我在ribbon加了一個edit物件想要和另一個slider同步。
在正情況可以工作良好,但一進入"最小化功能區"後就不行了。
原因和前個問題是一樣,但無法用同一個方法解決。
在最小化功能區時,我可以收到slider的position的通伖,但我去更新edit的是
原物件而顯示在瑩幕的卻是複本,所以看起來就像是edit物件沒有同步。
這裡的範例程式可以演示這個錯誤:
http://sdrv.ms/OV6Vlv
作者 : ccl0504(手動程式產生器) 貼文超過200則
[ 貼文 450 | 人氣 211 | 評價 930 | 評價/貼文 2.07 | 送出評價 2 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/8/24 下午 02:55:21

這個是繼承 class 後的解法
http://sdrv.ms/NNc4xd
改的有點亂....

我覺得比較好的方式是修改 MFC & 重 build MFC library, 不過 VS2010 缺少 MFC makefile
用 BCGPro 比較好的地方是修改不用動到 MFC dll
作者 : ccl0504(手動程式產生器) 貼文超過200則
[ 貼文 450 | 人氣 211 | 評價 930 | 評價/貼文 2.07 | 送出評價 2 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/8/24 下午 03:30:49

結果後來你 post 的改法還比較簡單
作者 : sunyear(coco) VC++卓越專家C++頂尖高手貼文超過2000則
[ 貼文 2421 | 人氣 1485 | 評價 6060 | 評價/貼文 2.5 | 送出評價 5 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/8/24 下午 06:29:25
>結果後來你 post 的改法還比較簡單
我花了一整天研究和試驗各種改法^^
結論是針對我提出的case,是可以克服。
但越深入了解後就發現,只要在pane浮動是採用複製的控製項,問題就會層出不窮。
我們實際在做介面時,介面上的控制單元常常會是互相關連的,例如選了某個選項,其它
一些控制項會連動(disable or enable),要改就會改個不完(大概所有的控制項都要改過)。
正本清源的的改法,應該是浮動時還是使用原來的控制項,不是複本。
但這可能改很大,除非MS給我美鈔,不然我不會去做^^
只是很好奇為什麼浮動時為什麼要用複本?本來toolbar的停駐和浮動就不需要複製啊?
只是更改toolbar style和重繪而已。
ribbon bar並不是繼承自tool bar這或許是一個原因,或許若是真的想把複本去掉,改下
去才會發現問題越來越大。

PS,題外話,試驗的過程有發現最早的那篇網路貼文裡儲存m_pSource是多餘的。
CMFCRibbonBaseElement裡面就有m_pOrginal的成員,也有現成的GetOriginal() 可以用^^
真正想要更新來源頂端(top level)的話,要從m_pOrginal找m_pOrginal的m_pOrginal直到m_pOrginal為NULL。
所以那篇貼文真的是太過大而化之了,不過是個很好的開始。
但更深入的話,要更新來源端,也不是使用m_pOrginal,而是要像我在RbnSlidCtrlErrorSolved所做的一樣,
先找到top level的ribbon bar,然後搜尋目標ID,更新所有找到的目標。
我看其它控制項也是這樣做而不是使用m_pOrginal。
無論如何,這都是因為使用複本而複雜化的不幸結果。
看看ribbon未來的版本會不會解決這問題。
暫時,我那個禁止使用複製的方法,簡單有效就先撐著用了^^

 板主 : 青衫 , Raymond
 > Visual C++ - 討論區
 - 最近熱門問答精華集
 - 全部歷史問答精華集
 - Visual C++ - 知識庫
  ■ 全站最新Post列表
  ■ 我的文章收藏
  ■ 我最愛的作者
  ■ 全站文章收藏排行榜
  ■ 全站最愛作者排行榜
  ■  月熱門主題
  ■  季熱門主題
  ■  熱門主題Top 20
  ■  本區Post排行榜
  ■  本區評價排行榜
  ■  全站專家名人榜
  ■  全站Post排行榜
  ■  全站評價排行榜
  ■  全站人氣排行榜
 請輸入關鍵字 
  開始搜尋
 
Top 10
評價排行
Visual C++
1 青衫 11070 
2 Raymond 10090 
3 Clier 7630 
4 小約翰 2500 
5 Cog 2030 
6 coco 1870 
7 aming 1410 
8 牧童哥 1400 
9 r2109 1380 
10 Akira 1350 
Visual C++
  專家等級 評價  
  一代宗師 10000  
  曠世奇才 5000  
  頂尖高手 3000  
  卓越專家 1500  
  優秀好手 750  
Microsoft Internet Explorer 6.0. Screen 1024x768 pixel. High Color (16 bit).
2000-2019 程式設計俱樂部 http://www.programmer-club.com.tw/
0.171875