If you ever wondered what a program like Audio Control looks like, or just what may be inside it, then you might want to have a look in the body of a
function included bellow. This code is written in a programming language called "C++" and is only one of hundreds of functions that were written when
creating Audio Control. These functions rely on other functions and services provided by the operating system. Besides functions, there are also types,
objects and other entities used in C++ programming. There are many other programming languages in addition to C++, all of which have certain positive
and negative aspects. For us, C++ is the best professional language for development as it possesses the power of raw low level languages and the power
of abstraction, which are both required for professional software development.
If you are a software development professional, you might note the use of memory atoms in the body of the function. Although in this function memory is barely used,
meaning that it hardly demonstrates the power of the Atomic Memory Model. However, you can still notice how easily
the memory is handled. All necessary checks during allocation are strictly and rigorously made, however their presence is hidden, thus it does not obstruct the already
complicated code.
| void CDestinationLineEntries::SortMixers( const MList< Pair< const MixerSortCriteria, bool > >& caSortOrder, const bool bLogicalOnly ) throw() |
| { |
| if( AudioMixerControl::mscUse == caSortOrder.GetHead()->GetLabelRef() ) |
| { |
| listMixersUseData.Empty(); |
| |
| HKEY hkRoot( NULL ); |
| |
if( ERROR_SUCCESS == RegCreateKeyEx( HKEY_CURRENT_USER,
((CAudioControlApp*)AfxGetApp())->GetAppRelativePath(),
0,
TEXT(""),
REG_OPTION_NON_VOLATILE,
KEY_QUERY_VALUE, NULL,
&hkRoot,
NULL ) ) |
| { |
| DWORD dwValueSize( 0 ); |
| |
if( ERROR_SUCCESS != RegQueryValueEx( hkRoot,
AUDIO_DEVICE_FIRST_CONTROL_USE_DATA_STORAGE_NAME,
NULL,
NULL,
NULL,
&dwValueSize ) ) |
| { |
| dwValueSize = 0; |
| } |
| |
| MMemoryPH< BYTE, HEAP_ZERO_MEMORY > memUseData( MMemory< BYTE >::MemUnits( (DWORD)dwValueSize ) ); |
| |
if( ERROR_SUCCESS == RegQueryValueEx( hkRoot,
AUDIO_DEVICE_FIRST_CONTROL_USE_DATA_STORAGE_NAME,
NULL,
NULL,
(BYTE*)(memUseData.GetMemory()),
&dwValueSize ) ) |
| { |
| const BYTE* pb1Data( memUseData ); |
| BYTE const* pb1FirstBefindData( pb1Data + memUseData.GetSizeBytes() ); |
| |
| while( pb1Data < pb1FirstBefindData ) |
| { |
Pair< DWORD, USHORT >::AddToHashTable( Pair< DWORD, USHORT >( *(DWORD*)pb1Data, *(USHORT*)(pb1Data + sizeof( DWORD )) ),
listMixersUseData,
true ); |
| |
| pb1Data += sizeof( DWORD ) + sizeof( USHORT ); |
| } |
| } |
| |
| RegCloseKey( hkRoot ); |
| } |
| |
| listMixersUseData.Accelerate(); |
| } |
| |
| |
| MList< Pair< CAdjustMixer*, MList< CAdjustMixer* > > > listFlowPriviliged; |
| MList< Pair< CAdjustMixer*, MList< CAdjustMixer* > > > listFlowNormal; |
| |
| for( DWORD dwMixer = 0; dwMixer < listMajorDependents.GetMembersCount(); dwMixer++ ) |
| { |
| if( (DWORD)MList< CAdjustMixer* >::Invalid == listListControlNeighbours.Find_H2T( listMajorDependents[dwMixer]->GetLabelRef() ) ) |
| { |
| MASSERT( AudioMixerControl::Major == listMajorDependents[dwMixer]->GetLabelRef()->GetMixerItem()->GetImportance() ); |
| |
| listFlowNormal.AddTail( listMajorDependents[dwMixer] ); |
| } |
| else |
| { |
| MASSERT( AudioMixerControl::Major == listMajorDependents[dwMixer]->GetLabelRef()->GetMixerItem()->GetImportance() ); |
| |
| listFlowPriviliged.AddTail( listMajorDependents[dwMixer] ); |
| } |
| } |
| |
| listMajorDependents.EmptyNoDelete(); |
| |
| |
| |
| const CAdjustMixer::Comparator< const CAdjustMixer* > tcComparator( caSortOrder ); |
| |
| while( !listFlowPriviliged.IsEmpty() ) |
| { |
| listFlowPriviliged.Accelerate(); |
| |
| DWORD dwExtremum( 0 ); |
| |
| for( dwMixer = dwExtremum + 1; dwMixer < listFlowPriviliged.GetMembersCount(); dwMixer++ ) |
| { |
| if( !tcComparator.IsOrdered( listFlowPriviliged[dwExtremum]->GetLabelRef(), listFlowPriviliged[dwMixer]->GetLabelRef() ) ) |
| { |
| dwExtremum = dwMixer; |
| } |
| } |
| |
| listMajorDependents.AddTail( listFlowPriviliged.RemoveMember( dwExtremum ) ); |
| |
| listMajorDependents.GetTail()->GetValueRef().SortList< CAdjustMixer::Comparator< const CAdjustMixer* > >( tcComparator ); |
| listMajorDependents.GetTail()->GetValueRef().Accelerate(); |
| } |
| |
| |
| while( !listFlowNormal.IsEmpty() ) |
| { |
| listFlowNormal.Accelerate(); |
| |
| DWORD dwExtremum( 0 ); |
| |
| for( dwMixer = dwExtremum + 1; dwMixer < listFlowNormal.GetMembersCount(); dwMixer++ ) |
| { |
| if( !tcComparator.IsOrdered( listFlowNormal[dwExtremum]->GetLabelRef(), listFlowNormal[dwMixer]->GetLabelRef() ) ) |
| { |
| dwExtremum = dwMixer; |
| } |
| } |
| |
| listMajorDependents.AddTail( listFlowNormal.RemoveMember( dwExtremum ) ); |
| |
| listMajorDependents.GetTail()->GetValueRef().SortList< CAdjustMixer::Comparator< const CAdjustMixer* > >( tcComparator ); |
| listMajorDependents.GetTail()->GetValueRef().Accelerate(); |
| } |
| |
| listMajorDependents.Accelerate(); |
| |
| listMixersSortedPtr.Empty(); |
| |
| for( dwMixer = 0; dwMixer < listMajorDependents.GetMembersCount(); dwMixer++ ) |
| { |
| listMixersSortedPtr.AddTail( new CAdjustMixer*( listMajorDependents[dwMixer]->GetLabelRef() ) ); |
| |
| MList< CAdjustMixer* >& listGroupMembers( listMajorDependents[dwMixer]->GetValueRef() ); |
| |
| for( DWORD dwGroupMember = 0; dwGroupMember < listGroupMembers.GetMembersCount(); dwGroupMember++ ) |
| { |
| listMixersSortedPtr.AddTail( new CAdjustMixer*( *listGroupMembers[dwGroupMember] ) ); |
| } |
| } |
| |
| listMixersSortedPtr.Accelerate(); |
| |
| |
| CWnd* pwndLastZOrder( this ); |
| |
| for( DWORD dwMixer = 0; dwMixer < listMixersSortedPtr.GetMembersCount(); dwMixer++ ) |
| { |
| MASSERT( IsWindow( pwndLastZOrder->m_hWnd ) ); |
| |
(*listMixersSortedPtr[dwMixer])->SetWindowPos( pwndLastZOrder,
0,
0,
0,
0,
SWP_NOACTIVATE |
SWP_NOCOPYBITS |
SWP_NOMOVE |
SWP_NOREDRAW |
SWP_NOSIZE |
SWP_NOOWNERZORDER ); |
| |
| pwndLastZOrder = (*listMixersSortedPtr[dwMixer]); |
| } |
| |
| |
| MASSERT( listMixersSortedPtr.GetMembersCount() == listMixers.GetMembersCount() ); |
| |
| if( !bLogicalOnly ) |
| { |
| SCROLLINFO si; |
| ZeroMemory( &si, sizeof( SCROLLINFO ) ); |
| si.cbSize = sizeof( SCROLLINFO ); |
| |
| GetScrollInfo( SB_VERT, &si, SIF_POS | SIF_PAGE | SIF_RANGE); |
| |
| MASSERT( int( min( si.nMax - si.nPage + Scroll_Min, (DWORD)max( Scroll_Min, si.nPos ) ) ) == si.nPos ); |
| |
| CRect rcMixer; |
| (*listMixersSortedPtr[0])->GetWindowRect( rcMixer ); |
| ScreenToClient( rcMixer ); |
| |
| rcMixer.top = - (si.nPos - Scroll_Min); |
| |
| for( DWORD dwMixer = 0; dwMixer < listMixersSortedPtr.GetMembersCount(); dwMixer++ ) |
| { |
| if( !(*listMixersSortedPtr[dwMixer])->IsWindowVisible() ) { continue; } |
| |
| rcMixer.bottom = rcMixer.top + uiScrollLine; |
| |
| (*listMixersSortedPtr[dwMixer])->MoveWindow( rcMixer, FALSE ); |
| |
| rcMixer.top = rcMixer.bottom; |
| } |
| |
| RedrawWindow(); |
| } |
| } |
Community Content
(To enter your comments you must be signed in. Log in or create FREE account.) |
|
|
|
|
| |