Skip to main content

Featured

Build docker image from multiple build contexts

Build docker image from multiple build contexts Building a docker image requires specifying a source of truth to include in the image from a local directory or a remote git repository. In the previous version, the docker BuildKit allows users to specify the build context from a single source of truth only. However, the engineers may need to have the context from different locations based on the type of files. For instance, icons, images or other resources that are not included in the same package, including the resource from other docker images. Fortunately, the Docker Buildx toolkit supports multiple build context flag for Docker 1.4. Let's learn how to use this new feature. The following list is a shortcut for jumping into a specific topic handy. What version of Docker is this tutorial targeting? How to specify the version of Dockerfile frontend? Ho

[CListCtrl]改變行高

由於MFC裡的CListCtrl並無提供改變行高的函式,因此就需要透過改變繪圖方式,來達到改變行高的效果。

這邊找到的參考資料如下:
1.Report control - with category
2.Changing Row Height in an owner drawn Control
3.CListCtrl 行高问题最终解决方法

裡面提到的方式都是使用OnSetFont()以及MeasureItem()來搭配使用。

另一種就是直接在OnNMCustomdrawLst()裡面,進行文字繪製。
Expandable List Control to Accept Multilines

OnNMCustomdrawLst()使用方式可參考[CListCtrl]改變儲存格文字顏色

由於使用OnNMCustomdrawLst()的方式比較複雜,所以底下就針對DrawItem()以及MeasureItem()兩個函式來說明。

在.h的部份:(SetFont()的部分稍後說明)
 void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) ;  
 afx_msg LRESULT    OnSetFont(WPARAM wParam, LPARAM lParam);  
 afx_msg void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);  

在message map部分:(無效的部份稍後說明)
 BEGIN_MESSAGE_MAP(CXListCtrl, CListCtrl)  
 //Multi-line  
     ON_MESSAGE(WM_SETFONT, OnSetFont)    //NOTE:無效  
     ON_WM_MEASUREITEM_REFLECT()        //NOTE:無效  
     ON_WM_MEASUREITEM()                //NOTE:無效  
 END_MESSAGE_MAP()  

在.cpp裡面要加上下列4個函式:
1.OnMeasureItem()
 void CXListCtrl::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)   
 {  
   CListCtrl::OnMeasureItem(nIDCtl, lpMeasureItemStruct);  
 }  

這邊為何要又呼叫一次CListCtrl::OnMeasureItem我就不曉得原因了,因上面參考連結是有這項。但程式卻都沒進入到此函式。所以不加應該也沒關係吧?!XD

2.MeasureItem()
 void CXListCtrl::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)   
 {  
     // Get the LOGFONT for the current font.  
     LOGFONT lf;  
     ::ZeroMemory(&lf, sizeof(lf));  
     CFont* pFont = GetFont();  
     ASSERT_VALID(pFont);  
     if (pFont)   
         VERIFY(pFont->GetLogFont(&lf));  
     int nAdj(2) ;        //Sample is 4  
     m_nLinesPerRow = max(m_nLinesPerRow, 1);  
     if (lf.lfHeight < 0)   
         lpMeasureItemStruct->itemHeight = ((-lf.lfHeight+nAdj) * (m_nLinesPerRow));  
     else   
         lpMeasureItemStruct->itemHeight = ((lf.lfHeight+nAdj) * (m_nLinesPerRow));  
 }  

這邊實際上用來變更高度的是lpMeasureItemStruct->itemHeight,但由於抓到的並不是完整的文字高度,單行沒問題,三行以上就出錯了。所以在範例的部份,有加上平移值。這邊測試結果,如果平移值與顯示行數差值大於等於2時,最後一行文字就會被蓋掉。所以這個值還是要做動態的會比較好。
如有需要做到每行高度不同的話,後面乘上的顯示行數就需要針對顯示文字的行是做動態處理。
目前還沒想到好作法,之後再回來補充。

3.OnSetFont()
 LRESULT CXListCtrl::OnSetFont(WPARAM wParam, LPARAM lParam)  
 {  
     CRect rc;  
     GetWindowRect(&rc);  
     WINDOWPOS wp;  
     wp.hwnd = this->m_hWnd;  
     wp.cx = rc.Width() ;  
     wp.cy = rc.Height() ;  
     wp.flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER;  
     LRESULT lrReturn(Default());  
     SendMessage(WM_WINDOWPOSCHANGED, 0, reinterpret_cast<LPARAM> (&wp));  
     return lrReturn;  
 }  

在範例裡,這個函式僅是用來觸發MeasureItem()更新動作的一個事件而已。觸發MeasureItem()的事件很獨特,就是讓畫面有所變動,然後系統就會送回重新繪製item的訊息,接下來就會進到MeasureItem()來重新繪製每個item的狀況。
此方法在範例中能成功,但我不管怎麼試,就是試不出來,也找不到原因。最後就在DrawItem()結束後,直接送出視窗訊息。

以上就是改變行高的作法

Comments

Popular Posts