//***********************************************************************/
// Introduction to Windows Programming
// Dialog.c
// created: 20/02/96 Rainer Döbele
// modified:
//***********************************************************************/
#include <windows.h> // we always need to include the windows header file
#include <string.h>
#include "dialog.h" // this is our own header file used e.g. to define ressource IDs
// Global variables
// Note: use globals only for constants which are valid thoughout
// the whole time of program execution
HINSTANCE hInstance; // Global Handle to Program Instance
// Prototypes of exported functions called by Windows
BOOL FAR PASCAL MainDlgProc(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam);
BOOL FAR PASCAL AboutDlgProc(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam);
// Prototypes of internally
void SortList(HWND hDlg,int idList,BOOL bCaseSensitive,BOOL bDescendingOrder);
// define the maximum length of a name
#define MAXNAMELEN 50
// Macros to overcome differences between Win16 and Win32
#ifdef WIN32
// Win32
#define CTLID LOWORD(wParam) // Control ID for WM_COMMAND
#define CTLMSG HIWORD(wParam) // Notification Message of Control
#define HCTL (HWND)lParam // window handle of control
#else
// Win16
#define CTLID wParam // Control ID for WM_COMMAND
#define CTLMSG HIWORD(lParam) // Notification Message of Control
#define HCTL (HWND)LOWORD(lParam) // window handle of control
#endif
//***********************************************************************/
int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow)
{
// Store the instance handle in case we need it later on
hInstance=hInst;
// Call our dialog
DialogBox(hInstance,MAKEINTRESOURCE(DLG_MAIN),NULL,MainDlgProc);
// Program was terminated
return TRUE;
}
//***********************************************************************/
BOOL FAR PASCAL MainDlgProc(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch (msg)
{
case WM_INITDIALOG:
// Disable all buttons that cannot be pushed at start
EnableWindow(GetDlgItem(hDlg,IDC_ADDNAME),FALSE);
EnableWindow(GetDlgItem(hDlg,IDC_SORTLIST),FALSE);
// Set Defaults for Option
CheckRadioButton(hDlg,IDC_ASCENDING,IDC_DESCENDING,IDC_ASCENDING);
CheckDlgButton(hDlg,IDC_CASEINSENSITIVE,TRUE);
// Set the maximum name length
SendDlgItemMessage(hDlg,IDC_NAME,EM_LIMITTEXT,MAXNAMELEN,0L);
break;
case WM_COMMAND:
// We received a notification message from a control
switch(CTLID)
{
case IDC_NAME: // Notification message from edit control
if (CTLMSG==EN_UPDATE)
{ // something changed in the edit field
// Check whether there is text in the name-field
int len=SendDlgItemMessage(hDlg,IDC_NAME,EM_LINELENGTH,0,0L);
EnableWindow(GetDlgItem(hDlg,IDC_ADDNAME),len);
}
break;
case IDC_NAMELIST: // Notification message from list control
if (CTLMSG==LBN_DBLCLK)
{ // User double-clicked a list item
// find out which item
int i=SendDlgItemMessage(hDlg,IDC_NAMELIST,LB_GETCURSEL,0,0L);
if (i>=0 && MessageBox(hDlg,"Do you want to delete this item","Confirm",MB_ICONQUESTION|MB_YESNO)==IDYES)
{ // Delete the item
SendDlgItemMessage(hDlg,IDC_NAMELIST,LB_DELETESTRING,i,0L);
}
}
break;
case IDC_ADDNAME: // Button Add name was clicked
{ char szName[MAXNAMELEN];
// Get the name from the edit control
GetDlgItemText(hDlg,IDC_NAME,szName,MAXNAMELEN);
// and add it to the list
SendDlgItemMessage(hDlg,IDC_NAMELIST,LB_ADDSTRING,0,(LPARAM)(LPSTR)szName);
// Delete the name in the deit control
SetDlgItemText(hDlg,IDC_NAME,NULL);
SetFocus(GetDlgItem(hDlg,IDC_NAME));
// Enable the sort button
EnableWindow(GetDlgItem(hDlg,IDC_SORTLIST),TRUE);
}
break;
case IDC_SORTLIST: // Button Sort list was clicked
{ // Get the sort options
BOOL bCaseInsensitive=IsDlgButtonChecked(hDlg,IDC_CASEINSENSITIVE);
BOOL bDescendingOrder=IsDlgButtonChecked(hDlg,IDC_DESCENDING);
// Now sort it
SortList(hDlg,IDC_NAMELIST,bCaseInsensitive,bDescendingOrder);
}
break;
// Menu Commands
case IDM_QUIT:
// user selected Quit from the menu
EndDialog(hDlg,TRUE);
break;
case IDM_ABOUT:
// Call about dialog
DialogBox(hInstance,MAKEINTRESOURCE(DLG_ABOUT),hDlg,AboutDlgProc);
break;
// Keyboard commands (only Return, Esc and F1 are forwarded)
case IDCANCEL:
{ int answer;
// User closed the window or pressed escape
answer=MessageBox(hDlg,"Do you really want to quit?","Confirm",MB_ICONQUESTION|MB_YESNO);
if (answer==IDYES) EndDialog(hDlg,FALSE);
}
break;
}
break;
#ifdef WIN32
// Set the background color for WIN32
case WM_CTLCOLORDLG:
case WM_CTLCOLORSTATIC:
case WM_CTLCOLORBTN:
SetBkColor((HDC)wParam,RGB(192,192,192));
return (BOOL)GetStockObject(LTGRAY_BRUSH);
#else
// Set the background color for WIN16
case WM_CTLCOLOR:
switch(HIWORD(lParam))
{
case CTLCOLOR_DLG:
case CTLCOLOR_STATIC:
case CTLCOLOR_BTN:
SetBkColor((HDC)wParam,RGB(192,192,192));
return GetStockObject(LTGRAY_BRUSH);
}
return FALSE; // use the defaults
#endif
case WM_DESTROY:
// Clean up if neccessary
// e.g. free allocated memory
break;
default:
// we did not processes the messages
// so let windows do it
return FALSE;
}
// we processed the dialogue messages
return TRUE;
}
//***********************************************************************/
void SortList(HWND hDlg,int idList,BOOL bCaseInsensitive,BOOL bDescendingOrder)
{ int nItems,i,j;
BOOL bSwap;
char buffer1[MAXNAMELEN],buffer2[MAXNAMELEN];
// Get the total number of list items
nItems=SendDlgItemMessage(hDlg,idList,LB_GETCOUNT,0,0L);
// Use Bubble Sort to sort the list
for (i=nItems;i>0;i--)
{
// Get the text of the first item in the list
SendDlgItemMessage(hDlg,idList,LB_GETTEXT,0,(LPARAM)(LPSTR)buffer1);
for (j=1;j<i;j++)
{ // Get the text of the next item in the list
SendDlgItemMessage(hDlg,idList,LB_GETTEXT,j,(LPARAM)(LPSTR)buffer2);
// compare the two strings
if (bCaseInsensitive) bSwap=(lstrcmpi(buffer1,buffer2)>0);
else bSwap=(strcmp(buffer1,buffer2)>0);
if (bDescendingOrder) bSwap=!bSwap;
// Swap the items if necessary
if (bSwap)
{ // since there is no LB_SETTEXT we delete the item first and then
// insert it again before the previous item
SendDlgItemMessage(hDlg,idList,LB_DELETESTRING,j,0L);
SendDlgItemMessage(hDlg,idList,LB_INSERTSTRING,j-1,(LPARAM)(LPSTR)buffer2);
}
else lstrcpy(buffer1,buffer2);
}
}
}
//***********************************************************************/
BOOL FAR PASCAL AboutDlgProc(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam)
{ // this is the dialogue procedure for the About dialogue
switch (msg)
{
case WM_INITDIALOG:
// Add code here to initialize Controls
break;
case WM_COMMAND:
// We received a notification message from a control
switch(CTLID)
{
case IDOK:
case IDCANCEL:
EndDialog(hDlg,TRUE);
break;
}
break;
default:
// we did not processes the messages
// so let windows do it
return FALSE;
}
// we processed the dialogue messages
return TRUE;
}
//***********************************************************************/
Back to tutorial