當前位置:編程學習大全網 - 源碼下載 - duilib怎麽兼容mfc控件

duilib怎麽兼容mfc控件

1. VK_TAB無效

2. 如果窗口中內嵌了WebBrowser,瀏覽器的CTRL+C、V無效,DEL無效

3. 如果窗口中內嵌了WebBrowser,則其他部分的滾動條將失效

由於我對duilib還不熟悉,當碰到這幾個問題時,壹下子沒了主意,只好請教於群內的各路大神,可更多的得到的答復是:為什麽要與MFC混用?

我想大家可能更多的是考慮壹個項目新建立,能直接使用duilib框架,還用什麽MFC,而且MFC似乎本來就不怎麽受人待見;但這裏我想說的是,對於若幹MFC的老項目,想切換UI到duilib上,難道說完全重寫過麽? 而且我已經做過遷移測試,將MFC項目的UI切換到duilib,可以比較簡單的在duilib的UI與舊的MFC窗口的邏輯中間加壹層代理轉發,這樣的工作量還是可以控制的。

扯遠了,最終經過多次詢問,還是在群裏碰到了有相關處理經驗的朋友,經過他們的指點,總算對這種兼容處理有了壹些思路,下面就將我目前的處理方案貼出來:

1. VK_TAB無效

這個需要在MFC的窗口類中處理 PreTranslateMessage ,將對於VK_TAB的處理強制交給duilib的 CPaintManagerUI::TranslateMessage 來處理

2. 如果窗口中內嵌了WebBrowser,瀏覽器的CTRL+C、V無效,DEL無效

這個與第壹點類似,將給duilib來處理即可

第1與2點代碼如下:

BOOL CMFCTestDlg::PreTranslateMessage( MSG* pMsg )

{

if( pMsg->message == WM_KEYDOWN)

{

{

if (pMsg->wParam == VK_ESCAPE || pMsg->wParam == VK_RETURN || pMsg->wParam == VK_TAB || pMsg->wParam == VK_DELETE)

{

if(m_dlgWnd.TranslateMessage(pMsg))

return TRUE;

}

else if (pMsg->wParam == 'C' || pMsg->wParam == 'V')

{

if( (GetKeyState(VK_CONTROL) & 0x8000))

{

m_dlgWnd.TranslateMessage(pMsg);

}

}

}

}

return CDialog::PreTranslateMessage(pMsg);

//TranslateMessage方法僅是轉而調用CPaintManagerUI::TranslateMessage

bool MainFrame::TranslateMessage( MSG* pMsg )

{

return m_PaintManager.TranslateMessage(pMsg);

}

這裏其實根本原因,原理我還沒搞清楚,請知道的補充壹下。

3. 如果窗口中內嵌了WebBrowser,則其他部分的滾動條將失效

這個問題以前就發現了,但在昨天才發現,如果將內嵌的瀏覽器拿掉的話,滾動條又正常了,進行了跟蹤,發現是由於當窗口中未選中任何的Edit或其他可操作的控件時,默認的焦點是在這個 WebBrowser 上[原因不詳],這樣鼠標中鍵滾輪滾動時,WM_MOUSEWHEEL消息會被路由到 LRESULT CActiveXWnd::HandleMessage,而此處對於消息 WM_MOUSEWHEEL是直接丟棄,導致了滾動條消息丟失了,按如下處理可以解決這個問題:

將WM_MOUSEWHEEL消息發給主窗口進行處理:

LRESULT CActiveXWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)

{

LRESULT lRes=0;

BOOL bHandled = TRUE;

switch( uMsg ) {

case WM_PAINT: lRes = OnPaint(uMsg, wParam, lParam, bHandled); break;

case WM_SETFOCUS: lRes = OnSetFocus(uMsg, wParam, lParam, bHandled); break;

case WM_KILLFOCUS: lRes = OnKillFocus(uMsg, wParam, lParam, bHandled); break;

case WM_ERASEBKGND: lRes = OnEraseBkgnd(uMsg, wParam, lParam, bHandled); break;

case WM_MOUSEACTIVATE: lRes = OnMouseActivate(uMsg, wParam, lParam, bHandled); break;

case WM_MOUSEWHEEL:

{

::PostMessage(::GetParent(GetHWND()), uMsg, wParam, lParam);

return 0;

}

break;

default:

bHandled = FALSE;

}

if( !bHandled ) return CWindowWnd::HandleMessage(uMsg, wParam, lParam);

return lRes;

}

按上述處理,目前這幾個問題基本得到了處理,我也敢在項目中應用了,但其實這裏還是有細節問題的,比如:

1. 按TAB鍵後,如果沒有WebBrowser,則按到最後,TAB就沒辦法切換有焦點的控件了,壹直出現叮叮的系統聲音[不可操作]

2. 按TAB鍵,如果有WebBrowser,則最終焦點進入WebBrowser後,不能切換出來了,只能通過鼠標來調整焦點;另外如果當前窗口沒選中任何控件,默認焦點在 WebBrowser 中,按TAB鍵則直接進入了WebBrowser 中。

3. 另外還有壹個問題duilib的問題,我這邊暫時簡單處理了壹下

所有的button類[button,check,option等]均會響應TABSTOP,這個可以在XML文件中通過keyboard屬性來設置,但庫中的CTreeViewUI中創建節點中會自動添加按鈕,這種需要手動將其設置為不響應TABSTOP:

pFolderButton->SetKeyboardEnabled(false);

pDottedLine->SetKeyboardEnabled(false);

pCheckBox->SetKeyboardEnabled(false);

pItemButton->SetKeyboardEnabled(false);

我目前直接將所有按鈕的默認接受屬性設置成了false,需要的時候針對需要的按鈕設置 keyboard屬性。

  • 上一篇:黃紅藍三種線分別是什麽線
  • 下一篇:請解釋壹下抓權,除權,充權的意思。謝謝妳。
  • copyright 2024編程學習大全網