You must have used the control panel applets that let you modify the system settings for Internet, Printer, Screen, Keyboard, etc. If we wish to invoke these applets in the middle of our application then invoking them directly would be more attractive than forcing the user to leave our application and manually invoke the control panel to make the desired changes.
Each control panel applet resides in a DLL with a file extension of ‘.cpl’. A cpl can contain more than one applet. So before invoking an applet we must figure out in which ‘.cpl’ file is it stored. The program presented here solves this problem. Firstly it lists all the ‘.cpl’ files present in the Windows System directory. On selecting a ‘.cpl’ file, a list of applets contained in it are displayed in another list box. The user can launch an applet by simply double clicking the applet name. Let us now see how do we go about building this program.
Create a dialog-based application called ‘Cpl’ and add two list boxes to the dialog template.
Add two control variables m_applet and m_cpllist of type CListBox for the list boxes. When the dialog appears on the screen the list box should display the list of ‘.cpl’ files in it. For this me must add these files to the list box in the OnInitdialog( ) function as shown below.
BOOL CCplDlg::OnInitDialog( )
{
// AppWizard generated code
// our code
char p[MAX_PATH] ;
::GetSystemDirectory ( p, MAX_PATH ) ;
CString path ;
path = p ;
path += “\\*.cpl” ;
CFileFind fd ;
if ( !fd.FindFile ( path ) )
return TRUE ;
CString filename ;
BOOL f = true ;
while ( f )
{
f = fd.FindNextFile( ) ;
filename = fd.GetFileName( ) ;
m_cpllist.AddString ( filename ) ;
}
fd.Close( ) ;
}
Since all the ‘.cpl’ files are stored in the system directory, we have first retrieved the path of the system directory using the function GetSystemDirectory( ). Next we have searched the ‘.cpl’ files in this path using the functions CFileFind::FindFile( ) and CFileFind::FindNextFile( ). Every file located this way is then added to the list box using CListBox::AddString( ).
When the user clicks on one of the files listed in the list box a LBN_SELCHANGE notification would be sent to our application. Our application should react to it by writing a handler for the notification. So we should now add the handler OnCplchange( ). Its code is given below:
void CCplDlg:: OnCplchange( )
{
int sel = m_cpllist.GetCurSel( ) ;
if ( sel == -1 )
return ;
CString cplname ;
m_cpllist.GetText ( sel, cplname ) ;
enumapplets ( cplname ) ;
}
Here we have simple retrieved the name of the selected cpl file and passed it to the enumapplets( ) function. This function should be added as a member function of the CCplDlg class. Its code is as under.
void CCplDlg::enumapplets ( CString cplname )
{
if ( loadcpl ( cplname ) != 0 )
freecpl( ) ;
}
The function loadcpl( ) loads the cpl file, whereas the function freecpl( ) removes it from memory. Both these functions must be added as member functions of the CCplDlg class. The code of loadcpl( ) function is given below.
int CCplDlg::loadcpl ( CString cplname )
{
m_applet.ResetContent( ) ;
m_hinst = ::LoadLibrary ( cplname ) ;
if ( m_hinst == NULL )
{
MessageBox ( “A Device Attached To The System Not
Functioning\nPossibly 16-bit CPL” ) ;
return 0 ;
}
m_proc = ( APPLET_PROC ) GetProcAddress ( m_hinst, “CPlApplet” ) ;
if ( m_proc == NULL )
{
MessageBox ( “Cannot get Proc Address” ) ;
return 0 ;
}
if ( !m_proc ( m_hWnd, CPL_INIT, 0L, 0L ) )
{
MessageBox ( “CPL Init Failed” ) ;
return 0 ;
}
int m_count ;
if ( ! ( m_count = ( int ) m_proc ( m_hWnd, CPL_GETCOUNT, 0L, 0L ) ) )
{
MessageBox ( “No Applet in CPL” ) ;
return 0 ;
}
CPLINFO cplinfo = { 0 } ;
char name[32] ;
for ( int i = 0 ; i < m_count ; ++i )
{
m_proc ( m_hWnd, CPL_INQUIRE, (LONG) i, (LPARAM) &cplinfo) ;
LoadString ( m_hinst, cplinfo.idName, name, 32 ) ;
m_applet.AddString ( name ) ;
}
return 1 ;
}
Here, to begin with, we have called the function CListBox::ResetContent( ) to empty the applet list box. Since a cpl is just a DLL we have loaded it in memory using the function LoadLibrary( ). Every cpl contains a standard entry-point function CplApplet( ) that receives and processes all requests in the form of CPL messages.
Once the DLL is loaded we have called GetProcAddress( ) to obtain the address of the exported function CPlApplet( ). This address is collected in a member variable (pointer to function) m_proc. Using this pointer then we have invoked the CPlApplet( ) function twice—to initialise the cpl and to obtain the number of applets the cpl supports. Once the count is determined we have again invoked the CPlApplet( ) function, this time to retrieve the name of the applet. This time we have passed the address of CPLINFO structure to it. CPlApplet( ) fills this structure with relevant information about the applet. The idName element of the structure contains the id of the applet. By passing this id to the LoadString( ) function the name of the applet is retrieved. Actually, LoadString( ) loads a string resource from the executable file associated with a module represented by the first parameter passed to LoadString( ). Next it copies the name of the applet into the buffer passed to it as the third parameter. Last parameter specifies the size of the buffer. The retrieved applet name is finally displayed in the applet list box. Do not forget to declare the following private variables:
HINSTANCE m_hinst ;
APPLET_PROC m_proc ;
The code for the freecpl( ) function is given below.
void CCplDlg::freecpl( )
{
m_proc ( m_hWnd, CPL_EXIT, 0L, 0L ) ;
FreeLibrary ( m_hinst ) ;
}
This function also calls the CPlApplet( ) function using m_proc. It sends the CPL_EXIT message to the applet to remove the cpl from memory.
What now remains to be done is launching the applet when the user double clicks on it. For this add a LBN_DBLCLK notification handler OnDblclkApplet( ) for the applet list box. The code for this handler is given below:
void CCplDlg::OnDblclkApplet( )
{
CString strcpl, strapp ;
int sel = -1 ;
sel = m_cpllist.GetCurSel( ) ;
m_cpllist.GetText ( sel, strcpl ) ;
sel = m_applet.GetCurSel( ) ;
loadcpl ( strcpl ) ;
m_proc ( m_hWnd, CPL_DBLCLK, ( LONG ) sel, NULL ) ;
freecpl( ) ;
}
Here the name of the selected cpl and the index of the selected applet are retrieved and then passed to the CplApplet( ) function along with the message CPL_ DBLCLK. And Voila! The applet would get launched.
Note that Win 9x contains some 16-bit cpls (sysdm.cpl, netcpl.cpl , and modem .cpl), in addition to the normal 32-bit cpls. If a Win 32 program calls LoadLibrary( ) to load a 16-bit module an error message “A device attached to the system is not functioning” is displayed.
Download your free Giveaway Riches list building by Jason James report today.
http://twurl.nl/hdol4f
Any tutorials out there how to become expert in List Building ?*”;
sometimes i get some difficulty in list building, it takes a lot of effort`~*