Coding Tips (JavaScript/CSS/VBA/Win32)

Useful code snippets, tips and some Windows applications

Some MFC Tips

1. How do I write code to display bitmap in column header of a list control?


Ans: The column names in a list control are displayed on a header control. We can obtain the pointer to the header control and set an image list on it. Following code shows how to do this.
CImageList m_img ;
m_img.Create ( IDB_BITMAP1, 16, 0, ILC_COLOR16 ) ;

CHeaderCtrl *h = m_l.GetHeaderCtrl( ) ; // where m_l is a control variable of list control
h -> SetImageList ( &m_img ) ;
m_l.InsertColumn ( 0, "A", LVCFMT_LEFT, 100 ) ;
m_l.InsertColumn ( 1, "B", LVCFMT_LEFT, 100 ) ;

HDITEM hitem ;
h -> GetItem ( 0, &hitem ) ;
hitem.mask = HDI_IMAGE | HDI_FORMAT ;
hitem.iImage = 0 ;
hitem.fmt = HDF_LEFT | HDF_IMAGE | HDF_STRING ;
h -> SetItem(0, &hitem);

m_img.Detach( ) ;
This code snippet displays a bitmap on the left side of zeroth column name.

2. How do I get an IP address of a local machine?


Ans: Follow the steps given below
1. Create an application with 'Windows Socket' support.
2. Add following code to the handler that is meant to return an IP address.
void mydialog::getIPaddress( )
{
CString hostname ; // stores local host name
CString IPAddress ; // stores IP address

char hname[256] ;

int nRetCode = gethostname ( hname, sizeof ( hname ) ) ;

if ( nRetCode != 0)
{
MessageBox ( "Host name not available" ) ;
return ;
}
else
hostname = hname ;

hostent FAR *lpHostEnt = gethostbyname ( hostname ) ;

if ( lpHostEnt == NULL )
{
MessageBox ( "IPAddress not available" ) ;
retrun ;
}

LPSTR lpAddr = lpHostEnt -> h_addr_list[0] ;

if ( lpAddr )
{
in_addr inAddr ;
memmove ( &inAddr, lpAddr, 4 ) ;
IPAddress = inet_ntoa ( inAddr ) ;
if ( IPAddress.IsEmpty( ) )
MessageBox ( "IPAddress not available" ) ;
}
}
To get an IP address of the local machine, we need to know the host name. Hence, we have called the Windows Socket's function gethostname( ) . This function returns the host name for the local machine. The function gethostbyname( ) called next retrieves the host information about the given host name. It returns a pointer to the hostent structure. This structure contains an IP address. To retrieve an IP address from this structure first we have copied first 4 bytes from lpAddr to inAddr. Then by calling inet_ntoa( ) function (again a windows socket function) we have retrieved an IP address.

3. How do I enumerate windows of currently running applications?


Ans: Follow the steps given below.

1. Create a dialog-based application.
2. Add a button and a list box control to the dialog template.
3. Add control variable say m_list for the list box to the dialog class.
4. Add the following code to the button handler:

void CDlgDlg::OnGetwindow( )
{
HWND hlb = ( HWND ) m_list ;
CWnd *h = GetDesktopWindow( ) ;
WindowsHandle ( h -> m_hWnd, ( LPARAM ) hlb ) ;
EnumWindows ( WindowsHandle, ( LPARAM ) hlb ) ;
}
Here, h stores the address of desktop window. A handle to the desktop window and a list box control is then passed to a callback function WindowsHandle( ). This function retrieves the title of the window and adds it to the list box. The function EnumWindows( ) called next enumerates all top-level windows on the screen by passing the handle to each window, in turn, to WindowsHandle( ) function. EnumWindows continues until the last top-level window is enumerated or the callback function returns FALSE. The code to the WindowsHandle( ) function is as shown below.
BOOL CALLBACK WindowsHandle ( HWND hwnd, LPARAM lParam )
{
CWnd *h = CWnd::FromHandle ( hwnd ) ;
CString hand ;
hand.Format ( "%p ", hwnd ) ;

CString title ;
h -> GetWindowText ( title ) ;

if ( title == "" )
title += "\"\" " ;
else
title = "\"" + title + "\" " ;

char cname[50] ;
GetClassName ( hwnd, cname, 50 ) ;

HWND hcb = ( HWND ) lParam ;
CWnd *pcombo = CWnd::FromHandle ( hcb ) ;
( ( CListBox * ) pcombo ) -> AddString ( hand + title + cname ) ;
return TRUE ;
}
4. How do I write code so that if I delete a file, then instead of getting the file deleted permanently it should go to the Recycle bin?

Ans: Use a shell API function called SHFileOperation( ). This function takes one argument which is a pointer to the SHFILEOPSTRUCT structure. This structure tells Windows what operation to perform, which files to delete, and other important information. SHFileOperation( ) also lets us copy, move, or rename one or several files. The following code snippet shows how to use this function.
void CRecycleDlg::OnDelete()
{
static SHFILEOPSTRUCT fp ;
char buff[] = "C:\\file1.txt\0\0" ;

fp.wFunc = FO_DELETE ;
fp.pFrom = ( LPCSTR ) buff ;
fp.fFlags = FOF_ALLOWUNDO ;

SHFileOperation ( &fp ) ;
}
When we use FO_DELETE operation to delete a file, SHFileOperation( ) attempts to place the deleted file in the Recycle Bin. Note that to send file to recycle bin we must set fFlags to FOF_ALLOWUNDO

5.How do I change the system colors programmatically?


Ans: An API function SetSysColors( ) is used to change the color of various display elements like caption bar, menu, desktop, etc of a window. This function takes the number of elements whose color has to be changed, a pointer to an array of integers which represents the display elements, and an array containing new RGB values for the elements whose color has to be changed. The following code snippet demonstrates the use of this function, where we have changed the color of caption bar of active window, menu and a window.
void CSyscolorDlg::OnSetColor( )
{
int color_array[] = { COLOR_ACTIVECAPTION, COLOR_MENU, COLOR_WINDOW } ;
COLORREF rgbvalues[] = { RGB ( 255, 0, 0 ) , RGB ( 255, 255, 0 ), RGB ( 0, 255, 255 ) } ;

SetSysColors ( 3, color_array, rgbvalues ) ;
}

6.How do I check programmatically, whether an Internet connection is available on my system?


Ans: The function InternetGetConnectedState( ) is used to find if an Internet connection is available on the system. This function returns true if an Internet connection is available. It also tells how the connection is available, i.e. whether the system uses modem, proxy or LAN to connect to the Internet. To make use of this function we need to #include 'wininet.h' file and link 'wininet.lib' file through 'Project | Settings | Link '. The following code snippet shows how we can use this function.
void CNetdlgDlg::OnCheckNet( )
{
DWORD flag ;
CString str = "" ;

if ( InternetGetConnectedState ( &flag, NULL ) )
str += "Internet connection is present\n" ;
else
str += "No Internet connection\n" ;

if ( flag & INTERNET_CONNECTION_LAN )
str += "The system uses a local area network to connect to the Internet" ;
if ( flag & INTERNET_CONNECTION_MODEM )
str += "The system uses a modem to connect to the Internet" ;
if ( flag & INTERNET_CONNECTION_PROXY )
str += "The system uses a proxy server to connect to the Internet\n" ;
MessageBox ( str ) ;
}


7. How do I extract programmatically, the path of the directory where the program currently running is situated?


Ans: Use GetModuleFileName( ) function. In Windows an '.EXE' or '.DLL' is called module. The GetModuleFileName( ) function takes three parameters, a handle to the module which in case of an '.EXE' would be NULL. The second and third parameters specify the address of buffer that stores the path and the size of the buffer respectively. Following code snippet demonstrates the use of this function.
void CGetmodnameDlg :: OnGetname( )
{
char buffer[MAX_PATH] ;
if ( GetModuleFileName ( NULL, buffer, MAX_PATH ) != 0 )
* ( strrchr ( buffer, '\\' ) + 1 ) = '\0' ;
MessageBox ( buffer ) ;
}
Here, we have called strrchr( ) function to eliminate the filename from the full path.

8. How do I write code to keep the bottom line in a multiple-line edit control visible?


Ans: To keep the bottom line in a multiple-line edit control visible, we need to know the total number of text lines added to the control. Once we get this number we can call LineScroll( ) function of CEdit class to scroll text of a multiple-line edit control.
BOOL CMuleditDlg :: OnInitDialog( )
{
// AppWizard generated code

int c = 0 ;
CString str1, str2 ;

CStdioFile f ( "Readme.txt", CFile::modeRead ) ;
while ( f.ReadString ( str1 ) != FALSE )
{
str2 += str1 + "\r\n" ;
c++ ;
}

m_edit.SetWindowText ( str2 ) ; // where m_edit is a control variable for edit control
m_edit.LineScroll ( c ) ;
return TRUE ;
}
Here, through a while loop we have read the contents of 'Readme.txt' file and copied it to the CString object str2. We have also counted the number of text lines read. Then after adding the text into the edit control we have called LineScroll( ) function to scroll text lines. Note that for the edit control added to the dialog template we must enable 'Auto HScroll' and 'Auto VScroll' properties.

9. How do I turn off the tool bar and status bar programmatically?


Ans: Write following code in a member function of CMainFrame class, and call this function through a handler or any other function when you want to turn off toolbar and status bar.
void CMainFrame::fun( )
{
if ( m_wndToolBar.IsWindowVisible( ) )
SendMessage ( WM_COMMAND, AFX_IDW_TOOLBAR, 0L ) ;
if ( m_wndStatusBar.IsWindowVisible( ) )
SendMessage ( WM_COMMAND, AFX_IDW_STATUS_BAR, 0L ) ;
}

10. How do I remove the window caption 'Untitled' that gets added to the window of an SDI application created with Doc/View support?


Ans: Write following statement to the PreCreateWindow( ) function of the CMainFrame class.
BOOL CMainFrame :: PreCreateWindow ( CREATESTRUCT& cs )
{
cs.style &= ~FWS_ADDTOTITLE ;
//AppWizard generated code
}
Here, we have removed FWS_ADDTOTITLE style from the window. FWS_ADDTOTITLE is an MFC-specific style that instructs the framework to add the document title to the window?s caption.

11.How do I ensure that on running an application a new document doesn't get created at startup?


Ans: To prevent creation of a new document at startup add the statement given below to InitInstance( ) function just before a call to ProcessShellCommand( ) function.

BOOL MyApp::InitInstance()
{
// AppWizard generated code
// prevent creartion of new document at startup
cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing ;
// Dispatch commands specified on the command line
if ( ! ProcessShellCommand ( cmdInfo ) )
return FALSE ;
// AppWizard generated code
return TRUE ;
}
Here, cmdInfo is an object of CCommandLineInfo class and m_nShellCommand is its data member. It indicates the shell command to be processed. We have specified the shell command to be processed as CCommandLineInfo::FileNothing. This turns off the display of a new document on startup.

12. How do I write code to add a resizable status bar on a resizable dialog box?


Ans: Follow the steps given below:

1. Create a dialog-based application
2. Add a pointer to CStatusBar class as a data member to the dialog class
3. Open OnInitDialog( ) function and add code shown below to it.
BOOL CDlgstatDlg::OnInitDialog( )
{
// AppWizard generated code
// Create the status bar.
HWND h = CreateWindowEx ( 0, STATUSCLASSNAME,
(LPCTSTR) NULL,
SBARS_SIZEGRIP | WS_CHILD,
0, 0, 0, 0, m_hWnd, 0,
AfxGetApp( ) -> m_hInstance, NULL ) ;

// Get the coordinates of the parent window's client area.
CRect r ;
GetClientRect ( &r ) ;

// allocate memory for the panes of status bar
int nopanes = 5 ;
int *indicators = new int[nopanes] ;

// set width for the panes
int width = r.right / nopanes ;
for ( int i = 0; i < nopanes ; i++ )
{
indicators[i] = width ; width += width ;
}
// Collect address in pointer to CStatusBar and call functions to set style
m_st = ( CStatusBar * ) CStatusBar::FromHandle ( h ) ;
m_st -> SendMessage ( SB_SETPARTS, (WPARAM) nopanes, (LPARAM) indicators ) ;
m_st -> SendMessage ( SB_SETTEXT, (WPARAM) 0 | SBT_POPOUT, (LPARAM) "Ready" ) ;
m_st -> ShowWindow ( 1 ) ;

return TRUE ;
}
4. To set pane text add a virtual function PreTranslateMessage( ) and enter code shown below to it.
BOOL CDlgstatDlg::PreTranslateMessage(MSG* pMsg)
{
if ( pMsg->message == WM_KEYDOWN )
{
switch ( pMsg -> wParam )
{
case VK_CAPITAL :
m_st -> SendMessage ( SB_SETTEXT, (WPARAM) 1 | SBT_RTLREADING, (LPARAM) "CAP" ) ;
break ;
}
}
return CDialog::PreTranslateMessage ( pMsg ) ;
}
5. To size the status bar when the dialog box resizes add handler for WM_SIZE message and code shown below to it.
void CDlgstatDlg::OnSize ( UINT nType, int cx, int cy )
{
CDialog::OnSize ( nType, cx, cy ) ;

CRect r ;
m_st -> GetWindowRect ( &r ) ;
r.right += cx ;
r.bottom += cy ;
m_st -> SetWindowPos ( &wndTop, r.left, r.top, r.Width( ), r.Height( ), SWP_SHOWWINDOW ) ;
}

13.How do I write code to remove a toolbar button programmatically?

Ans: This is shown in following code snippet.

void CMainFrame::OnDelete( )
{
m_wndToolBar.SendMessage ( TB_DELETEBUTTON, ( WPARAM ) 0 ) ;
}
Here, we have called SendMessage( ) function and passed it the message TB_DELETEBUTTON, as we want a toolbar button to be deleted and a zero-based index of the button to be deleted.

14.How do I change color of the status bar?


Ans: To change the color of status bar, we must access the status bar control lying under the status bar and call the SetBkColor( ) member function of the CStatusBarCtrl class.
m_wndStatusbar.GetStatusBarCtrl( ).SetBkColor ( RGB ( 255, 255, 0 ) ) ;

15. How do I write code that displays a progress control while copying contents?


Ans: Use SHFileOperation( ) function as shown below:
void MyDlgdlg::OnCopy( )
{
SHFILEOPSTRUCT s ;
::ZeroMemory ( &s, sizeof ( s ) ) ; // Initialize the structure

CString f = "C:\\MyFolder" ;
CString t = "D:\\" ;

char from [ MAX_PATH ], to [ MAX_PATH ] ; // buffer used to copy source and target path

strcpy ( from, f ) ;
int l = f.GetLength( ) ;
from[l+1] = '\0' ;

strcpy ( to, t ) ;
l = t.GetLength( ) ;
to[l+1] = '\0' ;

// Set the values in structure
s.hwnd = this -> m_hWnd ;
s.wFunc = FO_COPY ;
s.pFrom = ( LPCTSTR ) from ;
s.pTo = ( LPCTSTR ) to ;
s.fFlags = FOF_SIMPLEPROGRESS ;
s.lpszProgressTitle = "Copying files..." ;

::SHFileOperation ( &s ) ;
}