duilib relativepos屬性致使控件錯誤的bug修復

轉載請說明出處,謝謝~~html

        我在仿酷狗音樂播放器的開發日誌系列裏,曾經提到了這個bug,文章地址爲:http://blog.csdn.net/zhuhongshu/article/details/38145365。可是當時的開發日誌裏,我對bug的描述過於簡單。因此從新說明一下。git

       使用Duilib時,當爲一個控件指定了float屬性,也就是使用了絕對佈局,那個控件的位置和大小就固定了。同時Duilib提供了另外一個屬性:relativepos。這個屬性在官方的屬性列表裏面沒有給出,我這裏補充一下:github

<Attribute name="relativepos" default="0,0,0,0" type="RECT" comment="設置相對移動,float爲真時,分別表示橫縱向位移值,橫縱向縮放值,移動單位建議50或100"/>

      這個屬性只有在控件開啓float屬性後才能使用,爲的就是改變控件的位置和大小。雖然我不喜歡絕對佈局,可是當須要讓控件重疊時就只能用絕對佈局。使用了他,當父容器的大小改變了,開啓這個屬性的控件就會自動改變位置和大小,改變的幅度由屬性的具體數值決定。

     這原本是個很是棒的屬性。可是我使用後發現了bug。當控件開啓了這個屬性,咱們最小化窗體而後再最大化後控件的莫名其妙的位移了!我調試了好幾個小時,最後發現問題出在UIManager.cpp的MessageHandler函數WM_PAINT消息處理上,窗體最小化和最大化時都會獲取客戶區的大小並傳給子控件使其位移,可是最小化時獲取的窗體大小是錯誤的,因此致使了relativepos位置錯亂。函數

     解決方法是,在處理WM_PAINT消息時先用IsIconic函數判斷此時窗體是否最小化,只有非最小化時才調整子控件位置。
     原代碼以下:
佈局

						if( m_pRoot->IsUpdateNeeded() )
						{

							m_pRoot->SetPos(rcClient);	
							if( m_hDcBackground != NULL ) ::DeleteDC(m_hDcBackground);
							if( m_hbmpBackground != NULL ) ::DeleteObject(m_hbmpBackground);
							m_hDcBackground = NULL;
							m_hbmpBackground = NULL;
							m_pBmpBackgroundBits = NULL;
						}

   修改後爲:

						if( m_pRoot->IsUpdateNeeded() )
						{
							if( !::IsIconic(m_hWndPaint))  //redrain修復bug
								m_pRoot->SetPos(rcClient);	
							if( m_hDcBackground != NULL ) ::DeleteDC(m_hDcBackground);
							if( m_hbmpBackground != NULL ) ::DeleteObject(m_hbmpBackground);
							m_hDcBackground = NULL;
							m_hbmpBackground = NULL;
							m_pBmpBackgroundBits = NULL;
						}

      我把我本身使用的Duilib和Uilib庫都上傳到了GitHub,完整的Duilib庫代碼下載地址: 點擊打開連接

      這是我本身使用的Duilib和Uilib庫,修復了我在博客中說明的全部bug以及不少尚未去說明的bug,一樣也包含別人修復過的bug。庫裏面包含我擴展過的部分控件。以及添加了Duilib擴展羣羣主heat的透明異形窗體功能的支持。
     這個庫是我用vs2010修改的。若是你沒法正常打開個人庫或者編譯有問題,那麼建議把你須要的.h或者.cpp文件替換你本身的duilib庫對應的文件。
     我修改過的代碼,通常能夠經過搜索「redrain」找到對應的位置和修改時間
     此庫是我我的使用,因爲我水平所限,因此不保證我修改的代碼的質量。請你看過代碼後再決定是否使用。使用這個庫出現問題,不承擔任何責任。
ui


  Redrain  2014.10.30spa

相關文章
相關標籤/搜索