#include "stdafx.h" #include "propPage.h" #define DASSERT _ASSERTE #include "errorBase.h" #define CEDB_FAVORITES_NAME L"WMPlayer.Favorites" #define CEDB_PROP_ID_URL MAKEWPARAM( CEVT_LPWSTR, 1 ) #define CEDB_PROP_ID_NAME MAKEWPARAM( CEVT_LPWSTR, 2 ) CFavoritesPropertyPage::CFavoritesPropertyPage(): m_hwndList( NULL ), m_hDb( INVALID_HANDLE_VALUE ), m_fLeaveDBOpen( FALSE ), m_hCursorWait( NULL ) { m_dwTitleID = IDS_CE_PROPPAGE_FAVORITES_TITLE; m_hCursorWait = LoadCursor( NULL, MAKEINTRESOURCE( IDC_WAIT ) ); } CFavoritesPropertyPage::~CFavoritesPropertyPage() { _ASSERTE( INVALID_HANDLE_VALUE == m_hDb ); } // // Message Handlers // LRESULT CFavoritesPropertyPage::OnItemChanged(int idCtrl, LPNMHDR pnmh, BOOL& bHandled) { EnableControls(); return( 0 ); } LRESULT CFavoritesPropertyPage::OnEndLabelEdit(int idCtrl, LPNMHDR pnmh, BOOL& bHandled) { NMLVDISPINFO *pnmLV = (NMLVDISPINFO *)pnmh; if( NULL != pnmLV->item.pszText ) { LVITEM lvi; memset( &lvi, 0, sizeof(lvi) ); lvi.mask = LVIF_PARAM; lvi.iItem = pnmLV->item.iItem; lvi.lParam = (BOOL)TRUE; ListView_SetItem( m_hwndList, &lvi ); ListView_SetColumnWidth( m_hwndList, 0, LVSCW_AUTOSIZE ); ListView_SetColumnWidth( m_hwndList, 1, LVSCW_AUTOSIZE ); SetDirty( TRUE ); return( TRUE ); } return( 0 ); } LRESULT CFavoritesPropertyPage::OnKeyDown(int idCtrl, LPNMHDR pnmh, BOOL& bHandled) { LPNMLVKEYDOWN pnmKeyDown = (LPNMLVKEYDOWN)pnmh; if( NULL != pnmKeyDown ) { if( VK_DELETE == pnmKeyDown->wVKey && ::IsWindowEnabled( GetDlgItem( IDC_CE_PROPPAGE_FAVORITES_DELETE ) ) ) { PostMessage( WM_COMMAND, MAKEWPARAM( IDC_CE_PROPPAGE_FAVORITES_DELETE, 0 ), 0 ); } else if ( VK_INSERT == pnmKeyDown->wVKey && ::IsWindowEnabled( GetDlgItem( IDC_CE_PROPPAGE_FAVORITES_ADD ) ) ) { PostMessage( WM_COMMAND, MAKEWPARAM( IDC_CE_PROPPAGE_FAVORITES_ADD, 0 ), 0 ); } } return( 0 ); } LRESULT CFavoritesPropertyPage::OnAdd(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { CAddDialog dlg; HRESULT hr = S_OK; if( IDOK == dlg.DoModal( m_hWnd ) && 0 != wcslen( dlg.m_wszURL ) ) { hr = AddFavorite( dlg.m_wszURL, dlg.m_wszName, TRUE ); } EnableControls(); ShowError( hr ); return( 0 ); } LRESULT CFavoritesPropertyPage::OnDelete(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { HCURSOR hCurNormal = NULL; if( NULL != m_hCursorWait) { hCurNormal = SetCursor( m_hCursorWait ); } int iItem = -1; HRESULT hr = S_OK; m_fLeaveDBOpen = TRUE; while( SUCCEEDED( hr ) && -1 != (iItem = ListView_GetNextItem( m_hwndList, -1, LVNI_SELECTED ) ) ) { hr = ManageFavorites( iItem, TRUE ); UpdateWindow(); } m_fLeaveDBOpen = FALSE; if( INVALID_HANDLE_VALUE != m_hDb ) { CeCloseHandle( m_hDb ); m_hDb = INVALID_HANDLE_VALUE; } // // Since the user could have deleted their radio presets, allow them to do it again // EnableControls(); if( NULL != hCurNormal ) { SetCursor( hCurNormal ); } ShowError( hr ); return( 0 ); } // // IPropertyPage // STDMETHODIMP CFavoritesPropertyPage::Activate (HWND hWndParent, LPCRECT pRect, BOOL bModal) { HRESULT hr = S_OK; hr = IPropertyPageImpl::Activate( hWndParent, pRect, bModal ); if( SUCCEEDED( hr ) ) { hr = InitList(); } if( SUCCEEDED( hr ) ) { hr = EnableControls(); } ShowError( hr ); return( hr ); } STDMETHODIMP CFavoritesPropertyPage::Apply() { HCURSOR hCurNormal = NULL; if( NULL != m_hCursorWait) { hCurNormal = SetCursor( m_hCursorWait ); } int iItems = ListView_GetItemCount( m_hwndList ); HRESULT hr = S_OK; if( !m_bDirty ) { return( S_OK ); } m_fLeaveDBOpen = TRUE; if( -1 != iItems ) { while( SUCCEEDED( hr ) && iItems-- ) { hr = ManageFavorites( iItems, FALSE ); } } m_fLeaveDBOpen = FALSE; if( INVALID_HANDLE_VALUE != m_hDb ) { CeCloseHandle( m_hDb ); m_hDb = INVALID_HANDLE_VALUE; } SetDirty( FAILED( hr ) ); if( NULL != hCurNormal ) { SetCursor( hCurNormal ); } ShowError( hr ); return( hr ); } HRESULT CFavoritesPropertyPage::InitList() { HRESULT hr = S_OK; CEOID dbOID; HANDLE hDb = INVALID_HANDLE_VALUE; HRESULT hrFailCreate = S_OK; BOOL fNoItems = TRUE; HCURSOR hCurNormal = NULL; if( NULL != m_hCursorWait) { hCurNormal = SetCursor( m_hCursorWait ); } m_hwndList = GetDlgItem( IDC_CE_PROPPAGE_FAVORITES_FAVORITES ); if( NULL == m_hwndList ) { hr = HRESULT_FROM_WIN32( GetLastError() ); } if( SUCCEEDED( hr ) ) { LVCOLUMN lvc; WCHAR wszColumn[MAX_PATH]; ListView_SetExtendedListViewStyle( m_hwndList, LVS_EX_FULLROWSELECT ); lvc.mask = LVCF_TEXT; lvc.pszText = wszColumn; LoadString( _Module.GetResourceInstance(), IDS_NAME, wszColumn, sizeof(wszColumn)/sizeof(wszColumn[0]) ); ListView_InsertColumn( m_hwndList, 0, &lvc ); LoadString( _Module.GetResourceInstance(), IDS_CE_PROPPAGE_FAVORITES_URL, wszColumn, sizeof(wszColumn)/sizeof(wszColumn[0]) ); ListView_InsertColumn( m_hwndList, 1, &lvc ); } // // // // // if( SUCCEEDED( hr ) ) { dbOID = CeCreateDatabase( CEDB_FAVORITES_NAME, 0, 0, NULL ); if( 0 == dbOID ) { hrFailCreate = HRESULT_FROM_WIN32( CeGetLastError() ); if( SUCCEEDED( hrFailCreate ) ) { hrFailCreate = HRESULT_FROM_WIN32( CeRapiGetError() ); } } if( FAILED( hrFailCreate ) ) { dbOID = 0; } hDb = CeOpenDatabase( &dbOID, CEDB_FAVORITES_NAME, 0, CEDB_AUTOINCREMENT, NULL ); if( INVALID_HANDLE_VALUE == hDb ) { if( FAILED( hrFailCreate ) ) { hr = hrFailCreate; } else { hr = HRESULT_FROM_WIN32( CeGetLastError() ); if( SUCCEEDED( hr ) ) { hr = HRESULT_FROM_WIN32( CeRapiGetError() ); } } } } if( SUCCEEDED( hr ) ) { CEPROPVAL *pProps = NULL; WORD cProps = 0; LPBYTE lpBuffer = NULL; LPWSTR pszURL = NULL; LPWSTR pszName = NULL; DWORD dwSize = 0; while( 0 != (dbOID = CeReadRecordProps( hDb, CEDB_ALLOWREALLOC, &cProps, NULL, &lpBuffer, &dwSize ) ) ) { pszURL = NULL; pszName = NULL; _ASSERTE( NULL != lpBuffer ); if( NULL == lpBuffer ) { continue; } while( cProps-- ) { pProps = &(( CEPROPVAL *)lpBuffer)[cProps]; if( pProps->propid == CEDB_PROP_ID_NAME ) { pszName = pProps->val.lpwstr; } if( pProps->propid == CEDB_PROP_ID_URL ) { pszURL = pProps->val.lpwstr; } } if( NULL != pszName && NULL != pszURL ) { if( SUCCEEDED( AddFavorite( pszURL, pszName, FALSE ) ) ) { fNoItems = FALSE; } } LocalFree( lpBuffer ); cProps = 0; lpBuffer = NULL; dwSize = 0; } } if( SUCCEEDED( hr ) ) { if( fNoItems ) { ListView_SetColumnWidth( m_hwndList, 0, LVSCW_AUTOSIZE_USEHEADER ); ListView_SetColumnWidth( m_hwndList, 1, LVSCW_AUTOSIZE_USEHEADER ); } else { ListView_SetColumnWidth( m_hwndList, 0, LVSCW_AUTOSIZE ); ListView_SetColumnWidth( m_hwndList, 1, LVSCW_AUTOSIZE ); } } if( INVALID_HANDLE_VALUE != hDb ) { CeCloseHandle( hDb ); } if( NULL != hCurNormal ) { SetCursor( hCurNormal ); } return( hr ); } HRESULT CFavoritesPropertyPage::EnableControls() { int iSelectedItem = 0; long cItems = 0; iSelectedItem = ListView_GetNextItem( m_hwndList, -1, LVNI_SELECTED ); ::EnableWindow( GetDlgItem( IDC_CE_PROPPAGE_FAVORITES_DELETE ), -1 != iSelectedItem ); ::ShowWindow( GetDlgItem( IDC_CE_PROPPAGE_FAVORITES_EXPORT ), SW_HIDE ); return( S_OK ); } void CFavoritesPropertyPage::ShowError(HRESULT hrError) { if( FAILED( hrError ) ) { LPTSTR pszBuffer = NULL; if( 0 != FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, hrError, 0, (LPTSTR)&pszBuffer, 0, NULL ) ) { MessageBox( pszBuffer, NULL, MB_OK ); } if( NULL != pszBuffer ) { LocalFree( pszBuffer ); } } } HRESULT CFavoritesPropertyPage::ManageFavorites( int iItem, BOOL fRemove) { HRESULT hr = S_OK; WCHAR wszURL[INTERNET_MAX_URL_LENGTH]; WCHAR wszName[MAX_PATH]; LVITEM lvi; wszURL[0] = L'\0'; wszName[0] = L'\0'; memset( &lvi, 0, sizeof(lvi) ); lvi.iItem = iItem; lvi.mask = LVIF_PARAM; ListView_GetItem( m_hwndList, &lvi); if( 0 != lvi.lParam || fRemove ) { ListView_GetItemText( m_hwndList, iItem, 0, wszName, sizeof(wszName)/sizeof(wszName[0]) ); ListView_GetItemText( m_hwndList, iItem, 1, wszURL, sizeof(wszURL)/sizeof(wszURL[0]) ); if( 0 == wcslen( wszURL ) ) { hr = E_INVALIDARG; } if( SUCCEEDED( hr ) ) { hr = ManageFavorites( wszURL, wszName, fRemove ); } if( SUCCEEDED( hr ) ) { if( fRemove ) { ListView_DeleteItem( m_hwndList, iItem ); } else { lvi.lParam = 0; ListView_SetItem( m_hwndList, &lvi ); } } } return( hr ); } HRESULT CFavoritesPropertyPage::ManageFavorites( LPWSTR pszURL, LPWSTR pszName, BOOL fRemove ) { CEOID dbOID; HANDLE hDb = INVALID_HANDLE_VALUE; HRESULT hrFailCreate = S_OK; BOOL fFound = FALSE; BOOL fRename = FALSE; HRESULT hr = S_OK; if( INVALID_HANDLE_VALUE != m_hDb ) { hDb = m_hDb; } else { if( SUCCEEDED( hr ) ) { dbOID = CeCreateDatabase( CEDB_FAVORITES_NAME, 0, 0, NULL ); if( 0 == dbOID ) { hrFailCreate = HRESULT_FROM_WIN32( CeGetLastError() ); if( SUCCEEDED( hrFailCreate ) ) { hrFailCreate = HRESULT_FROM_WIN32( CeRapiGetError() ); } } if( FAILED( hrFailCreate ) ) { dbOID = 0; } hDb = CeOpenDatabase( &dbOID, CEDB_FAVORITES_NAME, 0, CEDB_AUTOINCREMENT, NULL ); if( INVALID_HANDLE_VALUE == hDb ) { if( FAILED( hrFailCreate ) ) { hr = hrFailCreate; } else { hr = HRESULT_FROM_WIN32( CeGetLastError() ); if( SUCCEEDED( hr ) ) { hr = HRESULT_FROM_WIN32( CeRapiGetError() ); } } } } } if( SUCCEEDED( hr ) ) { CEPROPVAL *pProps = NULL; CEPROPVAL props[2]; WORD cProps = 0; LPBYTE lpBuffer = NULL; DWORD dwSize = 0; memset( &props, 0, sizeof(props) ); props[0].propid = CEDB_PROP_ID_URL; props[0].val.lpwstr = pszURL; props[1].propid = CEDB_PROP_ID_NAME; props[1].val.lpwstr = pszName; while( 0 != (dbOID = CeReadRecordProps( hDb, CEDB_ALLOWREALLOC, &cProps, NULL, &lpBuffer, &dwSize) ) ) { _ASSERTE( NULL != lpBuffer ); if( NULL == lpBuffer ) { continue; } while( cProps-- ) { pProps = &(( CEPROPVAL *)lpBuffer)[cProps]; if( pProps->propid == CEDB_PROP_ID_NAME && 0 != wcsicmp( pProps->val.lpwstr, pszName ) ) { fRename = TRUE; } if( pProps->propid == CEDB_PROP_ID_URL && 0 == wcsicmp( pProps->val.lpwstr, pszURL ) ) { fFound = TRUE; break; } } LocalFree( lpBuffer ); cProps = 0; lpBuffer = NULL; dwSize = 0; if( fFound ) { break; } else { fRename = FALSE; } } if( fRemove ) { if( fFound ) { if( !CeDeleteRecord( hDb, dbOID ) ) { hr = HRESULT_FROM_WIN32( CeGetLastError() ); if( SUCCEEDED( hr ) ) { hr = HRESULT_FROM_WIN32( CeRapiGetError() ); } } } } else { if( ( !fFound || fRename ) && 0 == CeWriteRecordProps( hDb, fRename ? dbOID : 0, sizeof(props)/sizeof(props[0]), props ) ) { hr = HRESULT_FROM_WIN32( CeGetLastError() ); if( SUCCEEDED( hr ) ) { hr = HRESULT_FROM_WIN32( CeRapiGetError() ); } } } } if( INVALID_HANDLE_VALUE != hDb ) { if( m_fLeaveDBOpen ) { m_hDb = hDb; } else { CeCloseHandle( hDb ); } } return( hr ); } HRESULT CFavoritesPropertyPage::AddFavorite( LPWSTR pszURL, LPWSTR pszName, BOOL fDirty ) { HRESULT hr = S_OK; bool fAddedItem = false; LVITEM lvi; int iItem = -1; int cItems = ListView_GetItemCount( m_hwndList ); WCHAR wszURL[INTERNET_MAX_URL_LENGTH]; WCHAR wszName[MAX_PATH]; bool fFound = false; if( NULL == pszURL || NULL == pszName ) { hr = E_INVALIDARG; } if( SUCCEEDED( hr ) ) { // // Try to find the item first // while( cItems-- ) { ListView_GetItemText( m_hwndList, cItems, 1, wszURL, sizeof(wszURL)/sizeof(wszURL[0]) ); if( 0 == wcsicmp( pszURL, wszURL ) ) { iItem = cItems; fFound = true; break; } } // // If we didn't find it, then insert one // memset( &lvi, 0, sizeof(lvi) ); if( -1 == iItem ) { lvi.iItem = ListView_GetItemCount( m_hwndList ); iItem = ListView_InsertItem( m_hwndList, &lvi ); } else { lvi.iItem = iItem; } if( -1 != iItem ) { ListView_SetItemText( m_hwndList, iItem, 0, pszName ); ListView_SetItemText( m_hwndList, iItem, 1, pszURL ); lvi.mask = LVIF_PARAM; if( fFound ) { ListView_GetItem( m_hwndList, &lvi ); fDirty = lvi.lParam; if( !fDirty ) { ListView_GetItemText( m_hwndList, iItem, 0, wszName, sizeof(wszName)/sizeof(wszName[0]) ); fDirty = wcsicmp( pszName, wszName ); } } lvi.lParam = (LPARAM)fDirty; ListView_SetItem( m_hwndList, &lvi ); ListView_EnsureVisible( m_hwndList, iItem, FALSE ); ListView_SetColumnWidth( m_hwndList, 0, LVSCW_AUTOSIZE ); ListView_SetColumnWidth( m_hwndList, 1, LVSCW_AUTOSIZE ); } else { hr = E_OUTOFMEMORY; } } if( SUCCEEDED( hr ) ) { SetDirty( fDirty ); } return( hr ); } /////////////////////////////////////////////////////////////////////////////////////// // // // CAddDialog::CAddDialog() { m_wszURL[0] = L'\0'; m_wszName[0] = L'\0'; } LRESULT CAddDialog::OnURLChange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { EnableControls(); return( 0 ); } LRESULT CAddDialog::OnOK(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { SendDlgItemMessage( IDC_CE_PROPPAGE_FAVORITES_URL, WM_GETTEXT, sizeof(m_wszURL)/sizeof(m_wszURL[0]), (LPARAM)m_wszURL ); SendDlgItemMessage( IDC_CE_PROPPAGE_FAVORITES_NAME, WM_GETTEXT, sizeof(m_wszName)/sizeof(m_wszName[0]), (LPARAM)m_wszName ); EndDialog( IDOK ); return( 0 ); } LRESULT CAddDialog::OnCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { EndDialog( IDCANCEL ); return( 0 ); } LRESULT CAddDialog::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { SendDlgItemMessage( IDC_CE_PROPPAGE_FAVORITES_URL, EM_LIMITTEXT, sizeof(m_wszURL)/sizeof(m_wszURL[0]), 0 ); SendDlgItemMessage( IDC_CE_PROPPAGE_FAVORITES_NAME, EM_LIMITTEXT, sizeof(m_wszName)/sizeof(m_wszName[0]), 0 ); EnableControls(); return( 0 ); } void CAddDialog::EnableControls() { ::EnableWindow( GetDlgItem(IDOK), SendDlgItemMessage( IDC_CE_PROPPAGE_FAVORITES_URL, WM_GETTEXTLENGTH, 0, 0 ) != 0 ); }