directui的效果可以使用gdi、gdi+、directx、opengl實現,常用的有gdi和gdi+,後兩種有殺雞用牛刀的感覺。在網路上能找到此方面的教材
現在的軟體越來越多的有很炫目的介面,看來商家是越來越重視使用者體驗了,這個乙個流行趨勢呀。從技術上來說,美化介面基本有兩種方式:
1. directui 無控制代碼自繪控制項方式
2. 繼承mfc控制項類進行自繪
兩種各有優缺點,前者:實現複雜,控制複雜(如:訊息控制、各個控制項的基本設定),但自由度很大,你可以實現你能想象到的任何控制項。後者:實現簡單、但受制於mfc現有的控制項功能,最重要的是視窗一旦多,視窗背景的繪製和子視窗的繪製如若處理不當很容易造成區域性貼圖殘缺、拖拽視窗閃爍。所以一般在子視窗控制項不隨著主視窗拖拽而發生位置變化時採用後者的方式,其他建議採用前者的方式來完成。
由於以後會經常用到directui進行介面美化,於是抽空打了乙個directui的開發平台,方便以後開發,directui的開發平台要求如下:
1. 建立在vs2005的mfc dialog工程之上
2. 實現最基本的乙個空的dialog的**
3. **實現後,必須保留最基本的dialog的功能,如:最大化、最小化、雙擊標題欄、單擊工作列按鈕、拖拽等
4. 建立direcrui的引擎,已最簡便的方式便於以後的程式擴充套件
ok,開工了。先建立mfc的dialog的工程,保持所有屬性都預設,去掉【確定】和【退出】按鈕,如下:
之後我們必須解決乙個又乙個問題:
問題1:我們在什麼地方重繪視窗
有3個訊息處理可以重繪視窗:wm_erasebkgnd、wm_paint、wm_ncpaint,第乙個只重繪視窗整個背景,包括客戶區和非客戶區,不重绘子視窗;第二個只重繪客戶區,無法重繪非客戶區;第三個重繪非客戶區,也可以重繪客戶區。很明顯,我們應該處理第三個訊息,但第乙個訊息我們也需要處理,整個函式,直接 return true 即可。
問題2:頑固的系統預設標題欄
繪製第一步當然是重繪標題欄,在wm_ncpaint裡重繪標題欄後,發現那幾個系統按鈕在視窗啟用或者拖動的時候是不是閃現在介面上,相當的頑固,如下方法即可解決:
1. 截獲 wm_ncactivate 訊息,此訊息函式修改如下:
bool cskintestdlg::onncactivate(bool bactive)
2. 在 windowproc 函式中截獲繪製標題欄的訊息,**如下:
lresult cskintestdlg::windowproc(uint message, wparam wparam, lparam lparam)
return __super::windowproc(message, wparam, lparam);
}以上兩步,可以很完美的解決頑固的標題欄按鈕問題。
問題3:**的標題欄訊息處理
系統自帶的標題欄會隨著桌面主題的變化,標題欄的高度、系統按鈕的位置都會發生變化,這個相當煩人,咱們自定義的按鈕的位置大小一般都不會和系統按鈕相同。在處理這個問題的過程中,發現了一些導致了一些矛盾之處,幾乎很難調和(抱歉,時間太久了,很多的矛盾忘了),比如:客戶區座標和非客戶區座標轉換問題(兩套座標系,維護比較麻煩)、滑鼠在標題欄的雙擊區域、最大化的邊框問題... ... 結合這些問題,最後的處理方式是:截獲 wm_nccalcsize 訊息,修改非客戶區大小,讓非客戶區大小為0,所有自繪的東東都在客戶區實現,包括標題欄和邊框。**如下:
// 截獲此訊息為了讓視窗沒有標題欄和邊框
void cskintestdlg::onnccalcsize(bool bcalcvalidrects, nccalcsize_params* lpncsp)
問題4:沒有邊框的拖拽
問題3的衍生問題,沒有了邊框,當然就不能拖拽了,那我們自己處理拖拽吧,很簡單,截獲 wm_nchittest 訊息,**如下:
lresult cskintestdlg::onnchittest(cpoint point)
else if(point.x >= wndrect.right - nrdpos && point.y <= wndrect.top + nrdpos)
else if(point.x <= wndrect.left + nrdpos && point.y <= wndrect.top + nrdpos)
else if(point.x <= wndrect.left + nrdpos && point.y >= wndrect.bottom - nrdpos)
else if(point.x >= wndrect.right - ncheckpos)
else if(point.x <= wndrect.left + ncheckpos)
else if(point.y <= wndrect.top + ncheckpos)
else if(point.y >= wndrect.bottom - ncheckpos)
return __super::onnchittest(point);
}問題5:最大化的邊框問題
乙個正常的視窗,最大化後總是比當前螢幕大,剛好能將軟體的邊框蓋住,我實在不想要這個效果,那我只能自己處理最大化的效果了。
我自定乙個了最大化訊息,當自繪的最大化按鈕按下時,觸發這個訊息,接受到訊息後,取得螢幕的工作區域,然後將視窗改變到工作區域大小即可,**如下:
// 先記錄最大化前的視窗位置,以便恢復的時候用。
this->getwindowrect(&m_maxbeforerect);
crect wndrect(0, 0, 0, 0);
::systemparametersinfo(spi_getworkarea, 0, &wndrect, 0);
this->movewindow(&wndrect);
// 先記錄最大化前的視窗位置,以便恢復的時候用。
this->getwindowrect(&m_maxbeforerect);
crect wndrect(0, 0, 0, 0);
::systemparametersinfo(spi_getworkarea, 0, &wndrect, 0);
this->movewindow(&wndrect);
同樣恢復視窗的**如下:
// 恢復
crect wndrect(0, 0, 0, 0);
::systemparametersinfo(spi_getworkarea, 0, &wndrect, 0);
this->movewindow(&m_maxbeforerect);
問題6:自定義系統選單
系統預設的系統選單(滑鼠右擊工作列按鈕的選單),不能修改,那我們自己做乙個,查了很多訊息,終於找到啦,訊息 0x0313 就是滑鼠右擊工作列按鈕彈出選單的訊息,**如下:
定義訊息:
#define wm_popupsystemmenu 0x0313
截獲訊息:
on_message(wm_popupsystemmenu, onpopupsystemmenu)
處理訊息:
afx_msg lresult onpopupsystemmenu(wparam wparam, lparam lparam);
lresult cskintestdlg::onpopupsystemmenu(wparam wparam, lparam lparam)
這樣,想怎麼處理就怎麼處理。
最後,我們貼上**,基本的direcrui的平台就構建好了,效果如下:
搭建arm linux開發平台
在網上找了很多資料,才建立了自己的linux開發平台,這裡要感謝網路上的大牛們提供的資料,讓我少走了很多彎路,現在把我 搭建平台的步驟說明如下,主要是給自己乙個備份,呵呵。先介紹一下我使用的開發平台 開發板使用 帶s3c2440cpu的開發板,linux2.6 pc機上安裝的是ubuntu10.10...
ERP SYSTEM 開發平台搭建
devexpress fastreport unidac ehlib cnvcl 安裝框架包 erpcore 解壓後進入目錄framework,將下圖示有綠點的目錄加入delphi庫路徑 開啟工程framework,編譯erpcore.bpl 編譯安裝idewiz.bpl 開源 解壓後將下圖示有綠點...
MTK平台開發環境搭建
最近公司的專案差不多都做完了,趁新專案還沒來的時候學學東西。從朋友那裡搞來一套mtk的源 學學mtk的開發。選擇mtk是因為,它跟我的工作所用的平台相似,學起來方便一點,另外一點是它可以在pc上跑,不用自己去買硬體,成本不高。呵呵,從朋友那裡搞來的源 不用硬體,成本就只有時間了。我的那個朋友還真絕,...