?? propertylist.h
字號:
if( (m_dwExtStyle & PLS_EX_CATEGORIZED) && GET_X_LPARAM(lParam) < CATEGORY_INDENT ) {
prop->Activate(PACT_EXPAND, 0);
}
else {
if( prop->IsEnabled() ) prop->Activate(PACT_CLICK, lParam);
}
}
}
return lRes;
}
LRESULT OnLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
{
int x = _GetDragPos(GET_X_LPARAM(lParam));
if( m_iPrevious > 0 ) {
m_iMiddle += x - m_iPrevious;
Invalidate();
}
m_iPrevious = 0;
m_iPrevXGhostBar = 0;
bHandled = FALSE;
return 0;
}
LRESULT OnDblClick(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
LRESULT lRes = DefWindowProc(uMsg, wParam, lParam);
int idx = GetCurSel();
if( idx != -1 ) {
IProperty* prop = reinterpret_cast<IProperty*>(TBase::GetItemData(idx));
ATLASSERT(prop);
// Ask owner first
NMPROPERTYITEM nmh = { m_hWnd, GetDlgCtrlID(), PIN_DBLCLICK, prop };
if( ::SendMessage(GetParent(), WM_NOTIFY, nmh.hdr.idFrom, (LPARAM) &nmh) == 0 ) {
// Send DblClick action
if( prop->IsEnabled() ) prop->Activate(PACT_DBLCLICK, lParam);
}
}
return lRes;
}
LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL &bHandled)
{
// Column resize code added by Remco Verhoef, thanks.
if( m_iPrevious > 0 ) {
int x = _GetDragPos(GET_X_LPARAM(lParam));
if( m_iPrevXGhostBar != x ) {
if( m_iPrevXGhostBar ) _DrawGhostBar(m_iPrevXGhostBar);
m_iPrevXGhostBar = x;
_DrawGhostBar(m_iPrevXGhostBar);
}
return 0;
}
bHandled = FALSE;
return 0;
}
LRESULT OnSetCursor(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
POINT pt = { 0 };
::GetCursorPos(&pt);
ScreenToClient(&pt);
int iIndent = m_dwExtStyle & PLS_EX_CATEGORIZED ? CATEGORY_INDENT : 0;
if( pt.x == m_iMiddle + iIndent ) {
::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZEWE)));
return FALSE;
}
bHandled = FALSE;
return 0;
}
LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
// Custom styles
m_di.dwExtStyle = m_dwExtStyle;
// Standard colors
m_di.clrText = ::GetSysColor(COLOR_WINDOWTEXT);
m_di.clrBack = ::GetSysColor(COLOR_WINDOW);
m_di.clrSelText = ::GetSysColor(COLOR_HIGHLIGHTTEXT);
m_di.clrSelBack = ::GetSysColor(COLOR_HIGHLIGHT);
m_di.clrDisabled = ::GetSysColor(COLOR_GRAYTEXT);
// Border
m_di.clrBorder = ::GetSysColor(COLOR_BTNFACE);
if( !m_BorderPen.IsNull() ) m_BorderPen.DeleteObject();
m_di.Border = m_BorderPen.CreatePen(PS_SOLID, 1, m_di.clrBorder);
// Fonts
if( !m_TextFont.IsNull() ) m_TextFont.DeleteObject();
if( !m_CategoryFont.IsNull() ) m_CategoryFont.DeleteObject();
LOGFONT lf;
HFONT hFont = (HFONT)::SendMessage(GetParent(), WM_GETFONT, 0, 0);
if( hFont == NULL ) hFont = AtlGetDefaultGuiFont();
::GetObject(hFont, sizeof(lf), &lf);
m_di.TextFont = m_TextFont.CreateFontIndirect(&lf);
SetFont(m_di.TextFont);
if( (m_dwExtStyle & PLS_EX_XPLOOK) == 0 ) lf.lfWeight += FW_BOLD;
m_di.CategoryFont = m_CategoryFont.CreateFontIndirect(&lf);
// Text metrics
CClientDC dc(m_hWnd);
HFONT hOldFont = dc.SelectFont(m_di.TextFont);
dc.GetTextMetrics(&m_di.tmText);
dc.SelectFont(hOldFont);
// Repaint
Invalidate();
return 0;
}
LRESULT OnNavigate(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
switch( wParam ) {
case VK_UP:
case VK_DOWN:
{
_DestroyInplaceWindow();
SetCurSel(GetCurSel() + (wParam == VK_UP ? -1 : 1));
BOOL bDummy;
OnSelChange(0, 0, NULL, bDummy);
}
break;
}
return 0;
}
LRESULT OnUpdateProperty(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
{
// Updates a property value using an active editor window.
// The editor window uses this message to update the attached property class.
HWND hWnd = reinterpret_cast<HWND>(lParam);
ATLASSERT(hWnd);
if( !::IsWindow(hWnd) || m_iInplaceIndex == -1 ) return 0;
ATLASSERT(hWnd==m_hwndInplace);
IProperty* prop = reinterpret_cast<IProperty*>(TBase::GetItemData(m_iInplaceIndex));
ATLASSERT(prop);
if( prop == NULL ) return 0;
// Ask owner about change
NMPROPERTYITEM nmh = { m_hWnd, GetDlgCtrlID(), PIN_ITEMCHANGING, prop };
if( ::SendMessage(GetParent(), WM_NOTIFY, nmh.hdr.idFrom, (LPARAM) &nmh) == 0 ) {
// Set new value
if( !prop->SetValue(hWnd) ) ::MessageBeep((UINT)-1);
// Let owner know
nmh.hdr.code = PIN_ITEMCHANGED;
::SendMessage(GetParent(), WM_NOTIFY, nmh.hdr.idFrom, (LPARAM) &nmh);
// Repaint item
InvalidateItem(m_iInplaceIndex);
// Recycle in-place control so it displays the new value
// TODO: Traps condition where the SetValue() fails!
int idx = FindProperty(prop);
if( idx >= 0 && idx == m_iInplaceIndex ) _SpawnInplaceWindow(prop, idx);
}
return 0;
}
LRESULT OnCancelProperty(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
{
// Updates a property value using an active editor window.
// The editor window uses this message to update the attached property class.
HWND hWnd = reinterpret_cast<HWND>(lParam);
ATLASSERT(hWnd);
if( !::IsWindow(hWnd) || m_iInplaceIndex == -1 ) return 0;
ATLASSERT(hWnd==m_hwndInplace);
IProperty* prop = reinterpret_cast<IProperty*>(TBase::GetItemData(m_iInplaceIndex));
ATLASSERT(prop);
if( prop == NULL ) return 0;
// Repaint item
InvalidateItem(m_iInplaceIndex);
// Recycle in-place control so it displays the (old) value
int idx = FindProperty(prop);
if( idx >= 0 && idx == m_iInplaceIndex ) _SpawnInplaceWindow(prop, idx);
return 0;
}
LRESULT OnChangedProperty(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
// Updates a property value.
// A property class uses this message to make sure the corresponding editor window
// is updated as well.
IProperty* prop = reinterpret_cast<IProperty*>(lParam);
VARIANT* pVariant = reinterpret_cast<VARIANT*>(wParam);
ATLASSERT(prop && pVariant);
if( prop == NULL || pVariant == NULL ) return 0;
// Ask owner about change
NMPROPERTYITEM nmh = { m_hWnd, GetDlgCtrlID(), PIN_ITEMCHANGING, prop };
if( ::SendMessage(GetParent(), WM_NOTIFY, nmh.hdr.idFrom, (LPARAM) &nmh) == 0 ) {
// Set new value
// NOTE: Do not call this from IProperty::SetValue(VARIANT*) = endless loop
if( !prop->SetValue(*pVariant) ) ::MessageBeep((UINT)-1);
// Let owner know
nmh.hdr.code = PIN_ITEMCHANGED;
::SendMessage(GetParent(), WM_NOTIFY, nmh.hdr.idFrom, (LPARAM) &nmh);
}
// Locate the updated property index
int idx = FindProperty(prop);
// Repaint item
InvalidateItem(idx);
// Recycle in-place control so it displays the new value
if( idx >= 0 && idx == m_iInplaceIndex ) _SpawnInplaceWindow(prop, idx);
return 0;
}
LRESULT OnExpand(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
{
ATLASSERT(lParam);
ExpandItem(reinterpret_cast<IProperty*>(lParam));
return 0;
}
LRESULT OnCollapse(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
{
ATLASSERT(lParam);
CollapseItem(reinterpret_cast<IProperty*>(lParam));
return 0;
}
LRESULT OnSelChange(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
if( m_iPrevXGhostBar > 0 ) _DrawGhostBar(m_iPrevXGhostBar);
IProperty* prop = NULL;
int idx = GetCurSel();
if( idx != -1 ) {
prop = reinterpret_cast<IProperty*>(TBase::GetItemData(idx));
ATLASSERT(prop);
if( prop->GetKind() != PROPKIND_CATEGORY && prop->IsEnabled() ) {
_SpawnInplaceWindow(prop, idx);
prop->Activate(PACT_ACTIVATE, 0);
if( m_dwExtStyle & PLS_EX_SINGLECLICKEDIT ) {
if( prop->GetKind() == PROPKIND_EDIT ) prop->Activate(PACT_DBLCLICK, 0);
}
}
else {
_DestroyInplaceWindow();
}
}
// Let owner know
NMPROPERTYITEM nmh = { m_hWnd, GetDlgCtrlID(), PIN_SELCHANGED, prop };
::SendMessage(GetParent(), WM_NOTIFY, nmh.hdr.idFrom, (LPARAM) &nmh);
if( m_iPrevXGhostBar > 0 ) _DrawGhostBar(m_iPrevXGhostBar);
return 0;
}
// Owner draw methods
void DeleteItem(LPDELETEITEMSTRUCT lpDIS)
{
_DestroyInplaceWindow();
if( lpDIS->itemData ) delete reinterpret_cast<IProperty*>(lpDIS->itemData);
}
void MeasureItem(LPMEASUREITEMSTRUCT lpMIS)
{
lpMIS->itemHeight = m_di.tmText.tmHeight + 3;
}
void DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
if( lpDIS->itemID == -1 ) return; // If there are no list box items, skip this message.
CDCHandle dc(lpDIS->hDC);
RECT rc = lpDIS->rcItem;
IProperty* prop = reinterpret_cast<IProperty*>(lpDIS->itemData);
ATLASSERT(prop);
BYTE kind = prop->GetKind();
// Customize item
PROPERTYDRAWINFO di = m_di;
di.hDC = dc;
di.state = lpDIS->itemState & ~ODS_DISABLED;
if( lpDIS->itemID == (UINT) m_iInplaceIndex ) di.state |= ODS_COMBOBOXEDIT;
// Special style for removing selection when control hasn't focus
if( (di.dwExtStyle & PLS_EX_SHOWSELALWAYS) == 0 && (::GetFocus() != m_hWnd) ) {
di.state &= ~ODS_SELECTED;
}
// Prepare drawing
HFONT hOldFont = dc.SelectFont(di.TextFont);
// If this control is painted with categories
if( m_dwExtStyle & PLS_EX_CATEGORIZED ) {
// We paint a nice border in the gap with the plus/minus signs
HPEN hOldPen = dc.SelectPen(di.Border);
dc.MoveTo(rc.left + CATEGORY_INDENT - 1, rc.top);
dc.LineTo(rc.left + CATEGORY_INDENT - 1, rc.bottom);
if( m_dwExtStyle & PLS_EX_XPLOOK ) {
RECT rcIndent = { rc.left, rc.top, rc.left + CATEGORY_INDENT, rc.bottom };
dc.FillRect(&rcIndent, ::GetSysColorBrush(COLOR_3DFACE));
}
// Paint plus/minus sign if it's actually a category item
if( kind == PROPKIND_CATEGORY ) {
dc.SelectFont(di.CategoryFont);
CCategoryProperty* pCategory = static_cast<CCategoryProperty*>(prop);
POINT ptMiddle = { rc.left + (CATEGORY_INDENT / 2), rc.top + ((rc.bottom - rc.top) / 2) };
RECT rcSymbol = { ptMiddle.x - 4, ptMiddle.y - 4, ptMiddle.x + 5, ptMiddle.y + 5 };
dc.SelectStockPen(BLACK_PEN);
HBRUSH hOldBrush = dc.SelectStockBrush(NULL_BRUSH);
dc.Rectangle(&rcSymbol);
dc.SelectBrush(hOldBrush);
if( !pCategory->IsExpanded() ) {
dc.MoveTo(ptMiddle.x, ptMiddle.y - 2);
dc.LineTo(ptMiddle.x, ptMiddle.y + 3);
}
dc.MoveTo(ptMiddle.x - 2, ptMiddle.y);
dc.LineTo(ptMiddle.x + 3, ptMiddle.y);
}
dc.SelectPen(hOldPen);
rc.left += CATEGORY_INDENT;
}
// Calculate rectangles for the two sides
RECT rcName = rc;
RECT rcValue = rc;
rcName.right = rc.left + m_iMiddle;
rcValue.left = rc.left + m_iMiddle + 1;
// Special handling of XP-like categories
if( kind == PROPKIND_CATEGORY && (m_dwExtStyle & PLS_EX_XPLOOK) != 0 ) {
rcName.right = rcValue.left = rc.right;
}
// Draw name
di.rcItem = rcName;
prop->DrawName(di);
// Draw value
// Thanks to Pascal Binggeli who suggested the Inplace-editor
// check below...
if( (int) lpDIS->itemID != m_iInplaceIndex ) {
di.rcItem = rcValue;
dc.FillSolidRect(&rcValue, di.clrBack);
if( !prop->IsEnabled() ) di.state |= ODS_DISABLED;
prop->DrawValue(di);
}
// Paint borders
HPEN hOldPen = dc.SelectPen(di.Border);
dc.MoveTo(rc.left, rc.bottom - 1);
dc.LineTo(rc.right, rc.bottom - 1);
// Not painting middle border if XP look (thanks to Ludvig A Norin)
if( !(kind == PROPKIND_CATEGORY && (m_dwExtStyle & PLS_EX_XPLOOK) != 0) ) {
dc.MoveTo(rc.left + m_iMiddle, rc.top);
dc.LineTo(rc.left + m_iMiddle, rc.bottom - 1);
}
dc.SelectPen(hOldPen);
dc.SelectFont(hOldFont);
}
};
class CPropertyListCtrl : public CPropertyListImpl<CPropertyListCtrl>
{
public:
DECLARE_WND_SUPERCLASS(_T("WTL_PropertyList"), GetWndClassName())
};
#endif __PROPERTYLIST__H
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -