//+------------------------------------------------------------------------- // // Microsoft Windows // // Copyright (C) Microsoft Corporation, 1999 - 1999 // // File: tasksym.cpp // //-------------------------------------------------------------------------- #include "stdafx.h" #include "tasks.h" #include "stgio.h" #include #include "symbinfo.h" #include "pickicon.h" #include "util.h" const int NUM_SYMBOLS = (sizeof(s_rgEOTSymbol)/sizeof(s_rgEOTSymbol[0])); static const int s_cxIcon = 32; // size of an icon static const int s_cxSelectionMargin = 4; // additional border for selection static const int s_cxIconGutter = 10; // gutter space between icons (keep this even) //############################################################################ //############################################################################ // // Implementation of class CEOTSymbol // //############################################################################ //############################################################################ CEOTSymbol::~CEOTSymbol() { } bool CEOTSymbol::operator == (const CEOTSymbol &rhs) { return ( (m_iconResource == rhs.m_iconResource) && (m_value == rhs.m_value) && (m_ID == rhs.m_ID) ); } void CEOTSymbol::SetIcon(const CSmartIcon & smartIconSmall, const CSmartIcon & smartIconLarge) { m_smartIconSmall = smartIconSmall; m_smartIconLarge = smartIconLarge; } /*+-------------------------------------------------------------------------* * * CEOTSymbol::Draw * * PURPOSE: * * PARAMETERS: * HDC hdc : * RECT * lpRect : * bool bSmall : * * RETURNS: * void * *+-------------------------------------------------------------------------*/ void CEOTSymbol::Draw(HDC hdc, RECT *lpRect, bool bSmall) const { // if the icons already exist, Draw has been called before OR this symbol has a custom icon that as been // assigned the icons directly using SetIcon if((HICON)m_smartIconSmall == NULL) { m_smartIconSmall.Attach((HICON)::LoadImage(_Module.GetResourceInstance(), MAKEINTRESOURCE(m_iconResource), IMAGE_ICON, 16, 16, 0)); } if((HICON)m_smartIconLarge == NULL) { m_smartIconLarge.Attach((HICON)::LoadImage(_Module.GetResourceInstance(), MAKEINTRESOURCE(m_iconResource), IMAGE_ICON, 32, 32, 0)); } /* * Preserve icon shape when BitBlitting it to a * mirrored DC. */ DWORD dwLayout=0L; if ((dwLayout=GetLayout(hdc)) & LAYOUT_RTL) { SetLayout(hdc, dwLayout|LAYOUT_BITMAPORIENTATIONPRESERVED); } DrawIconEx(hdc, lpRect->left, lpRect->top, bSmall ? m_smartIconSmall : m_smartIconLarge, bSmall? 16 : 32, bSmall? 16 : 32, 0, NULL, DI_NORMAL); /* * Restore the DC to its previous layout state. */ if (dwLayout & LAYOUT_RTL) { SetLayout(hdc, dwLayout); } } /*+-------------------------------------------------------------------------* * * CEOTSymbol::IsMatch * * PURPOSE: Checks to see whether str1 is one of the strings contained in the * comma separated list str2. * * PARAMETERS: * CStr & str1 : * CStr & str2 : * * RETURNS: * bool: true if str1 is contained in str2, else false. * *+-------------------------------------------------------------------------*/ bool CEOTSymbol::IsMatch(CStr &str1, CStr &str2) { // trim spaces off either end. str1.TrimLeft(); str1.TrimRight(); CStr strTemp; int length; while((length = str2.GetLength()) != 0 ) { int index = str2.Find(TEXT(',')); if(index!=-1) { strTemp = str2.Left(index); // index is the pos of the ',' so we're OK. str2 = str2.Right(length - index -1); } else { strTemp = str2; str2.Empty(); } strTemp.TrimLeft(); strTemp.TrimRight(); // compare str1 and strTemp if( str1.CompareNoCase((LPCTSTR)strTemp)==0) return true; // match } return false; } int CEOTSymbol::FindMatchingSymbol(LPCTSTR szDescription) // finds a symbol matching the given description. { CStr strDescription = szDescription; int iSelect = -1; for(int i = 0; i0) iSelect = CEOTSymbol::FindMatchingSymbol((LPCTSTR)strName.data()); } /* * select the icon for this task */ LV_ITEM item; ZeroMemory(&item, sizeof(item)); item.iItem = iSelect; item.mask = LVIF_STATE; item.state = LVIS_FOCUSED | LVIS_SELECTED; item.stateMask = LVIS_FOCUSED | LVIS_SELECTED; m_listGlyphs.SetItem(&item); m_listGlyphs.EnsureVisible(iSelect, 0); return 0; } /*+-------------------------------------------------------------------------* * CTaskSymbolDlg::OnCtlColorStatic * * WM_CTLCOLORSTATIC handler for CTaskSymbolDlg. *--------------------------------------------------------------------------*/ LRESULT CTaskSymbolDlg::OnCtlColorStatic(UINT mMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { HBRUSH hbrRet = NULL; switch (::GetDlgCtrlID (((HWND) lParam))) { /* * for the custom icon preview window and its well, if we're using a * custom icon, return a COLOR_WINDOW brush so the static won't paint * the background with COLOR_3DFACE */ case IDC_CustomIcon: case IDC_CustomIconWell: if (m_bCustomIcon) hbrRet = GetSysColorBrush (COLOR_WINDOW); break; } /* * if we didn't supply a brush, let this message go through to DefWindowProc */ if (hbrRet == NULL) bHandled = false; return ((LPARAM) hbrRet); } /*+-------------------------------------------------------------------------* * CTaskSymbolDlg::OnIconSourceChanged * * BN_CLICKED handler for CTaskSymbolDlg. *--------------------------------------------------------------------------*/ LRESULT CTaskSymbolDlg::OnIconSourceChanged(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled ) { m_bCustomIcon = (wID == IDC_CustomIconRadio); SC scNoTrace = ScEnableControls (wID); return (0); } /*+-------------------------------------------------------------------------* * CTaskSymbolDlg::ScEnableControls * * Enables the controls belonging to a particular radio button on the * symbol dialog *--------------------------------------------------------------------------*/ SC CTaskSymbolDlg::ScEnableControls (int id) { DECLARE_SC (sc, _T("CTaskSymbolDlg::ScEnableControls")); /* * validate input */ ASSERT ((id == IDC_CustomIconRadio) || (id == IDC_MMCIconsRadio)); if (! ((id == IDC_CustomIconRadio) || (id == IDC_MMCIconsRadio))) return (sc = E_INVALIDARG); /* * controls to be enabled when "Custom Icon" radio button is selected */ static const int nCustomIconCtlIDs[] = { IDC_CustomIcon, IDC_CustomIconWell, IDB_SELECT_TASK_ICON, 0 // terminator }; /* * controls to be enabled when "MMC Icons" radio button is selected */ static const int nMMCIconCtlIDs[] = { IDC_GLYPH_LIST, IDC_DESCRIPTION, IDC_DESCRIPTION2, IDC_DESCRIPTIONLabel, IDC_DESCRIPTION2Label, 0 // terminator }; const int* pnEnableIDs = NULL; const int* pnDisableIDs = NULL; /* * pick the right sets of controls to enable/disable */ if (id == IDC_CustomIconRadio) { pnEnableIDs = nCustomIconCtlIDs; pnDisableIDs = nMMCIconCtlIDs; } else { pnEnableIDs = nMMCIconCtlIDs; pnDisableIDs = nCustomIconCtlIDs; } /* * enable/disable the controls */ for (int i = 0; pnEnableIDs[i] != 0; i++) ::EnableWindow (GetDlgItem (pnEnableIDs[i]), true); for (int i = 0; pnDisableIDs[i] != 0; i++) ::EnableWindow (GetDlgItem (pnDisableIDs[i]), false); return (sc); } LRESULT CTaskSymbolDlg::OnSymbolChanged(int id, LPNMHDR pnmh, BOOL& bHandled ) { NMLISTVIEW* pnmlv = (NMLISTVIEW *) pnmh; if(! ((pnmlv->uNewState & LVNI_FOCUSED) && (pnmlv->iItem !=-1)) ) return 0; int nItem = pnmlv->iItem; CStr strDescription; int ID = s_rgEOTSymbol[nItem].GetID(); strDescription.LoadString(_Module.GetResourceInstance(), ID); // get the string. SetDlgItemText(IDC_DESCRIPTION, (LPCTSTR) strDescription); CStr strDescription2; int ID2 = s_rgEOTSymbol[nItem].GetIDSecondary(); if(ID2) strDescription2.LoadString(_Module.GetResourceInstance(), ID2); // get the string. SetDlgItemText(IDC_DESCRIPTION2, (LPCTSTR) strDescription2); return 0; } LRESULT CTaskSymbolDlg::OnCustomDraw(int id, LPNMHDR pnmh, BOOL& bHandled ) { NMCUSTOMDRAW* pnmcd = (NMCUSTOMDRAW *) pnmh; switch(pnmcd->dwDrawStage & ~CDDS_SUBITEM) { case CDDS_PREPAINT: // the initial notification return CDRF_NOTIFYITEMDRAW; // we want to know about each item's paint. case CDDS_ITEMPREPAINT: DrawItem(pnmcd); return CDRF_SKIPDEFAULT; // we've drawn the whole item ourselves default: return 0; } } void CTaskSymbolDlg::DrawItem(NMCUSTOMDRAW *pnmcd) { DECLARE_SC(sc, TEXT("CTaskSymbolDlg::DrawItem")); int nItem = pnmcd->dwItemSpec; HDC &hdc = pnmcd->hdc; LV_ITEM item; ZeroMemory(&item, sizeof(item)); item.iItem = nItem; item.mask = LVIF_STATE; item.stateMask = (UINT) -1; //get all the state bits. m_listGlyphs.GetItem(&item); /* * get the icon rect for the item and offset it downward by the size * of our border margin */ RECT rectIcon; m_listGlyphs.GetItemRect(nItem, &rectIcon, LVIR_ICON); OffsetRect (&rectIcon, 0, s_cxSelectionMargin); /* * Make a slightly inflated copy the icon rectangle to draw in the * selection color. We inflate to make the selection stand out a little * more for large icons. */ RECT rectBackground = rectIcon; InflateRect (&rectBackground, s_cxSelectionMargin, s_cxSelectionMargin); bool bWindowHasFocus = (GetFocus() == (HWND)m_listGlyphs); bool bSelected = item.state & LVIS_SELECTED; bool bDisabled = !m_listGlyphs.IsWindowEnabled(); // Create the select rectangle or empty the rectangle. int nBackColorIndex = (bDisabled) ? COLOR_3DFACE : (bSelected) ? COLOR_HIGHLIGHT : COLOR_WINDOW; FillRect (hdc, &rectBackground, (HBRUSH) LongToHandle(nBackColorIndex+1)); // draw the symbol icon s_rgEOTSymbol[nItem].Draw(hdc, &rectIcon); if(bWindowHasFocus && bSelected) ::DrawFocusRect(hdc, &rectBackground); //ReleaseDC(hdc); DONT release the DC! } BOOL CTaskSymbolDlg::OnOK() { int nItem = m_listGlyphs.GetSelectedIndex(); /* * make sure we've selected an item */ if (( m_bCustomIcon && (m_CustomIconLarge == NULL)) || (!m_bCustomIcon && (nItem == -1))) { CStr strError; strError.LoadString(GetStringModule(), IDS_SYMBOL_REQUIRED); MessageBox(strError, NULL, MB_OK | MB_ICONEXCLAMATION); return (false); } if (m_bCustomIcon) m_ConsoleTask.SetCustomIcon(m_CustomIconSmall, m_CustomIconLarge); else m_ConsoleTask.SetSymbol(s_rgEOTSymbol[nItem].GetValue()); return TRUE; } /*+-------------------------------------------------------------------------* * * CTaskSymbolDlg::OnSelectTaskIcon * * PURPOSE: Uses the shell-provided icon picker dialog to allow the user to select * a custom icon for the console task. * * PARAMETERS: * WORD wNotifyCode : * WORD wID : * HWND hWndCtl : * BOOL& bHandled : * * RETURNS: * LRESULT * *+-------------------------------------------------------------------------*/ LRESULT CTaskSymbolDlg::OnSelectTaskIcon(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled ) { DECLARE_SC(sc, TEXT("CTaskSymbolDlg::OnSelectTaskIcon")); static CStr s_strCustomIconFile; static int s_nIconIndex = 0; int nIconIndex = s_nIconIndex; TCHAR szIconFile[MAX_PATH]; /* * shouldn't get here unless we think we're using a custom icon */ ASSERT (m_bCustomIcon); /* * reuse the last custom icon source; if it's not available, * default to mmc.exe */ if (s_strCustomIconFile.IsEmpty()) { LPTSTR pszCustomIconFile = s_strCustomIconFile.GetBuffer (MAX_PATH); sc = ScCheckPointers (pszCustomIconFile, E_OUTOFMEMORY); if (sc) { MMCErrorBox (sc); return (0); } GetModuleFileName (NULL, pszCustomIconFile, MAX_PATH); s_strCustomIconFile.ReleaseBuffer(); } lstrcpy (szIconFile, s_strCustomIconFile); if (PickIconDlg (m_hWnd, szIconFile, countof (szIconFile), &nIconIndex)) { TCHAR szIconFile2[MAX_PATH]; ExpandEnvironmentStrings(szIconFile, szIconFile2, MAX_PATH); /* * remember the user's selection for next time */ s_strCustomIconFile = szIconFile; s_nIconIndex = nIconIndex; // need to extract and copy the icon rather than use LoadImage, because LoadImage uses a custom icon CSmartIcon smartIconTemp; smartIconTemp.Attach(::ExtractIcon (_Module.m_hInst, szIconFile2, nIconIndex)); m_CustomIconSmall.Attach((HICON) ::CopyImage((HICON)smartIconTemp, IMAGE_ICON, 16, 16, LR_COPYFROMRESOURCE)); m_CustomIconLarge.Attach((HICON) ::CopyImage((HICON)smartIconTemp, IMAGE_ICON, 32, 32, LR_COPYFROMRESOURCE)); /* * update the custom icon preview window */ m_wndCustomIcon.SetIcon (m_CustomIconLarge); m_wndCustomIcon.InvalidateRect (NULL); } return 0; }