如有需要變更執行檔的執行優先順序,可呼叫SetPriorityClass Function()來達成需求。
第一個參數是目前程序的HANDLE,第二個參數則為要設定的順序參數。
目前測試結果是有效~~XDD
[C++]在Class內宣告靜態float常數
一般對compiler而言,要宣告class內的靜態常數,只能宣告成int的形態。
如果要宣告成
則Compiler會出現「a member of type "const float" cannot have a in-class initializer」
因此,如想要在class內宣告靜態的float,則需先在class內宣告個靜態的float,但不給予值。並在*.cpp給定此常數值即可:
參考連結:static const float in C++. why not?
如果要宣告成
static const float STATIC_FLOAT = 1.F;
則Compiler會出現「a member of type "const float" cannot have a in-class initializer」
因此,如想要在class內宣告靜態的float,則需先在class內宣告個靜態的float,但不給予值。並在*.cpp給定此常數值即可:
*.h
class CTestClass
{
static cosnt float STATIC_FLOAT;
...
...
}
*.cpp
const flaot CTestClass::STATIC_FLOAT = 1.F;
參考連結:static const float in C++. why not?
[CListCtrl]欄位顯示多行文字
由於MFC提供的CListCtrl並無輸入多行文字功能,因此也需要從繪圖的部分下手。
由於ClistCtrl一次也只能顯示一行文字,因此在進行顯示多行文字之前,需先讓CListCtrl的欄位可以隨著文字段數變動。這邊可以參考[CListCtrl]改變行高 。(參考文獻在上述連結內都有)
在顯示多行文字部分,則是透過改寫DrawItem()來讓文字可以斷行。
使用前,需先將CListCtrl的Owner Draw Fixed屬性打開(坊間流傳的SetExtendedStyle(LVS_OWNERDRAWFIXED)並無效果)。(PS.在這邊浪費了好幾個小時@@,果然跑不起來還是要先查設定@@)
在.h部分
在.cpp部分
目前這個範例裡面還看不出是怎麼讓文字斷行的,但可確定的是,由於這個function會重新變更欄位的字體與背景顏色。因此當同時還有使用到OnNMCustomdrawLst()的話,OnNMCustomdrawLst()所繪製的顏色會被DrawItem()所覆蓋掉(因OnNMCustomdrawLst()比DrawItem()早執行),所以這邊要注意。
如有找到換行的方法,之後再補上。
PS.測試結果,DrawText似乎會在遇到newline時,就會把後面的文字自動輸出到下一行。
Problem:
1.在移動欄位title時,欄位內顯示之文字並不會像CListCtrl一樣,會加上"..."來代表有文字被遮蓋。
看來這邊是需要自行處理。(變更欄位大小時,畫面不會更新到其他地方)
2.上一次顯示文字之尾端總是會殘留在下一個欄位的開頭,這邊也需要另外再處理。
3.此範例所繪製的文字會貼齊於Cell的最左側邊界,會與CListCtrl顯示結果不同。
新找到的:Multi-line List Control
這篇提供的方法可以解決P.1、P.2、P3的問題。
差別在於,這篇提供的畫文字方法是CDC::DrawTextEx。這樣就可以讓CListCtrl自行去處理上述之問題,不然要手動處理的話,倒是挺麻煩的。如此一來,函式也變得比較乾淨了。
修改過後的函式如下:
由於ClistCtrl一次也只能顯示一行文字,因此在進行顯示多行文字之前,需先讓CListCtrl的欄位可以隨著文字段數變動。這邊可以參考[CListCtrl]改變行高 。(參考文獻在上述連結內都有)
在顯示多行文字部分,則是透過改寫DrawItem()來讓文字可以斷行。
使用前,需先將CListCtrl的Owner Draw Fixed屬性打開(坊間流傳的SetExtendedStyle(LVS_OWNERDRAWFIXED)並無效果)。(PS.在這邊浪費了好幾個小時@@,果然跑不起來還是要先查設定@@)
在.h部分
afx_msg void OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct);
在.cpp部分
void CXListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
TCHAR lpBuffer[256];
LV_ITEM lvi;
lvi.mask = LVIF_TEXT | LVIF_PARAM ;
lvi.iItem = lpDrawItemStruct->itemID ;
lvi.iSubItem = 0;
lvi.pszText = lpBuffer ;
lvi.cchTextMax = sizeof(lpBuffer);
VERIFY(GetItem(&lvi));
LV_COLUMN lvc, lvcprev ;
::ZeroMemory(&lvc, sizeof(lvc));
::ZeroMemory(&lvcprev, sizeof(lvcprev));
lvc.mask = LVCF_WIDTH | LVCF_FMT;
lvcprev.mask = LVCF_WIDTH | LVCF_FMT;
for ( int nCol=0; GetColumn(nCol, &lvc); nCol++)
{
if ( nCol > 0 )
{
// Get Previous Column Width in order to move the next display item
GetColumn(nCol-1, &lvcprev) ;
lpDrawItemStruct->rcItem.left += lvcprev.cx ;
lpDrawItemStruct->rcItem.right += lpDrawItemStruct->rcItem.left ;
}
// Get the text
::ZeroMemory(&lvi, sizeof(lvi));
lvi.iItem = lpDrawItemStruct->itemID;
lvi.mask = LVIF_TEXT | LVIF_PARAM;
lvi.iSubItem = nCol;
lvi.pszText = lpBuffer;
lvi.cchTextMax = sizeof(lpBuffer);
VERIFY(GetItem(&lvi));
CDC* pDC;
pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
//--------------- Full selection - highlight -----------------------
if ( lpDrawItemStruct->itemState & ODS_SELECTED )
{
pDC->FillSolidRect(&lpDrawItemStruct->rcItem, GetSysColor(COLOR_HIGHLIGHT)) ;
pDC->SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT)) ;
}
else
{
pDC->FillSolidRect(&lpDrawItemStruct->rcItem, GetSysColor(COLOR_WINDOW)) ;
pDC->SetTextColor(GetSysColor(COLOR_WINDOWTEXT)) ;
}
//--------------- Full selection - highlight -----------------------
pDC->SelectObject(GetStockObject(DEFAULT_GUI_FONT));
UINT uFormat = DT_LEFT ;
::DrawText(lpDrawItemStruct->hDC, lpBuffer, strlen(lpBuffer),
&lpDrawItemStruct->rcItem, uFormat) ;
pDC->SelectStockObject(SYSTEM_FONT) ;
//Enable measureitem().
this->OnSetFont(NULL, NULL); //配合MeasureItem()用的
}
}
目前這個範例裡面還看不出是怎麼讓文字斷行的,但可確定的是,由於這個function會重新變更欄位的字體與背景顏色。因此當同時還有使用到OnNMCustomdrawLst()的話,OnNMCustomdrawLst()所繪製的顏色會被DrawItem()所覆蓋掉(因OnNMCustomdrawLst()比DrawItem()早執行),所以這邊要注意。
如有找到換行的方法,之後再補上。
PS.測試結果,DrawText似乎會在遇到newline時,就會把後面的文字自動輸出到下一行。
Problem:
1.在移動欄位title時,欄位內顯示之文字並不會像CListCtrl一樣,會加上"..."來代表有文字被遮蓋。
看來這邊是需要自行處理。(變更欄位大小時,畫面不會更新到其他地方)
2.上一次顯示文字之尾端總是會殘留在下一個欄位的開頭,這邊也需要另外再處理。
3.此範例所繪製的文字會貼齊於Cell的最左側邊界,會與CListCtrl顯示結果不同。
新找到的:Multi-line List Control
這篇提供的方法可以解決P.1、P.2、P3的問題。
差別在於,這篇提供的畫文字方法是CDC::DrawTextEx。這樣就可以讓CListCtrl自行去處理上述之問題,不然要手動處理的話,倒是挺麻煩的。如此一來,函式也變得比較乾淨了。
修改過後的函式如下:
void CXListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
LPDRAWITEMSTRUCT lpDrawHighLight = new DRAWITEMSTRUCT();
CString cstrSubitemText = "";
CRect rcSubItemRect;
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); //不用釋放
LV_ITEM lvi;
rcSubItemRect.SetRectEmpty();
LV_COLUMN lvc, lvcprev ;
::ZeroMemory(&lvc, sizeof(lvc));
::ZeroMemory(&lvcprev, sizeof(lvcprev));
lvc.mask = LVCF_WIDTH | LVCF_FMT;
lvcprev.mask = LVCF_WIDTH | LVCF_FMT;
//lpDrawItemStruct->rcItem為目前所要畫出文字的row的邊界。
for ( int nCol=0; GetColumn(nCol, &lvc); nCol++)
{
// Get Previous Column Width in order to move the next display item
if ( nCol > 0 )
{
GetColumn(nCol-1, &lvcprev) ;
lpDrawItemStruct->rcItem.left += lvcprev.cx;
//lpDrawItemStruct->rcItem.right += lpDrawItemStruct->rcItem.left; //會影響到最後一個SubItem的顯示長度。
}
//--------------- Full selection - highlight -----------------------
//Let Drawed highlight like the CListCtrl do it.
::memcpy(lpDrawHighLight, lpDrawItemStruct, sizeof(DRAWITEMSTRUCT));
lpDrawHighLight->rcItem.left += this->GetStringWidth(" "); //保留開頭的空白。讓行為同CListCtrl。
if ( lpDrawItemStruct->itemState & ODS_SELECTED )
{
pDC->FillSolidRect(&lpDrawHighLight->rcItem, GetSysColor(COLOR_HIGHLIGHT)) ;
pDC->SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT)) ;
}
else
{
pDC->FillSolidRect(&lpDrawHighLight->rcItem, GetSysColor(COLOR_WINDOW)) ;
pDC->SetTextColor(GetSysColor(COLOR_WINDOWTEXT)) ;
}
//--------------- Full selection - highlight -----------------------
//-------------- Draw item -------------------------
pDC->SelectObject(GetStockObject(DEFAULT_GUI_FONT));
if ( !this->GetSubItemRect(lpDrawItemStruct->itemID, nCol, LVIR_BOUNDS, rcSubItemRect) ) {
continue; };
//::DrawText(lpDrawItemStruct->hDC, lpDisplayBuf, nShowWordsLen, &lpDrawText->rcItem, uFormat) ;
rcSubItemRect.left += this->GetStringWidth(" ");
rcSubItemRect.right -= this->GetStringWidth(" ");
cstrSubitemText = this->GetItemText(lpDrawItemStruct->itemID, nCol);
pDC->DrawTextEx(cstrSubitemText, rcSubItemRect, (DT_LEFT|DT_NOPREFIX|DT_TOP|DT_WORD_ELLIPSIS), NULL);
pDC->SelectStockObject(SYSTEM_FONT) ;
//-------------- Draw item -------------------------
//Enable measureitem().
this->OnSetFont(NULL, NULL);
} //End of for ( int nCol=0; GetColumn(nCol, &lvc); nCol++)
if ( lpDrawHighLight != NULL ) {
delete lpDrawHighLight;
lpDrawHighLight = NULL;
}
}
[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()的部分稍後說明)
在message map部分:(無效的部份稍後說明)
在.cpp裡面要加上下列4個函式:
1.OnMeasureItem()
這邊為何要又呼叫一次CListCtrl::OnMeasureItem我就不曉得原因了,因上面參考連結是有這項。但程式卻都沒進入到此函式。所以不加應該也沒關係吧?!XD
2.MeasureItem()
這邊實際上用來變更高度的是lpMeasureItemStruct->itemHeight,但由於抓到的並不是完整的文字高度,單行沒問題,三行以上就出錯了。所以在範例的部份,有加上平移值。這邊測試結果,如果平移值與顯示行數差值大於等於2時,最後一行文字就會被蓋掉。所以這個值還是要做動態的會比較好。
如有需要做到每行高度不同的話,後面乘上的顯示行數就需要針對顯示文字的行是做動態處理。
目前還沒想到好作法,之後再回來補充。
3.OnSetFont()
在範例裡,這個函式僅是用來觸發MeasureItem()更新動作的一個事件而已。觸發MeasureItem()的事件很獨特,就是讓畫面有所變動,然後系統就會送回重新繪製item的訊息,接下來就會進到MeasureItem()來重新繪製每個item的狀況。
此方法在範例中能成功,但我不管怎麼試,就是試不出來,也找不到原因。最後就在DrawItem()結束後,直接送出視窗訊息。
以上就是改變行高的作法
這邊找到的參考資料如下:
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()結束後,直接送出視窗訊息。
以上就是改變行高的作法
Subscribe to:
Posts (Atom)
Build docker image from multiple build contexts
Build docker image from multiple build contexts ...
-
參考資料: Input Input Manager 測試手把 :PS Analog gamepad Script語言:C# Unity 版本:3.4 Unity提供了3種輸入裝置可以使用,鍵盤、滑鼠、以及遊戲手把。 ...
-
寫法很簡單,就像下列寫法: if ( *szStr ) { .... } 因為*szStr == szStr[0],且char[]是以NULL-Terminate來判定字串是否結束,所以只要判定陣列的第一個值是不是為零,就可知道是否為空字串。 如需檢查是否為空字...