Why to use CALLBACK function and how command line argument works with different options?

  • Thread starter Thread starter aditya satya prakash
  • Start date Start date
A

aditya satya prakash

Guest
Hi,

I am working on my first project as an intern. The project is on C++, VC++, and Threading concepts. I was given this project to understand the workflow and the concepts used in that workflow.

When I was going through the project and the below code I understood the few concepts. And need few clarifications. I Even tried to get the clarifications from my peer and colleagues but I didn't get the clear and satisfied answers and solutions. As a beginner I wanted to clarify my doubts to get the strong foundation to kick start the project.

I have studied C++, VC++ and having basic theoretical and basic programming as well as technical knowledge.

Here the project and the workflow is to check if the UPS battery is connected to the computer or not. If it is not connected we should show notification dialog.

Please help me by clarifying my doubts.

1. My understanding is WinMain is the program entry point and execution starts from here. In this WinMain function, we are calling "CreateWindow" to create an instance of a window. If the window has created and exist then we are calling the function "EMRGenericDialogBox" CALLBACK function.

Here why should we use CALLBACK function? what is the importance of this?

2. The function "EMRGenericDialogBox", is the Generic function which display a particular dialog based on the command line.

Here how the command line argument is having different options? And how it handles different command line options? ( I have written this function in the below)


3. And also I know the Mutex synchronization technique is to synchronization threads across the process. I wanted to know Here why should we use Mutex? And How it works in this workflow? And also I didn't understand how CREATE_EMR_MUTEX is defining and why it is using in the below function:

Blow is my code with the functions:

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
HWND hWnd;

InitCommonControls();

_tcscpy(szWindowClass, "EMR_RUN_CLASS");
_tcscpy(szTitle, "EMR_RUN");

// Initialize global strings
MyRegisterClass(hInstance);

// Perform application initialization:
hInst = hInstance; // Store instance handle in our global variable

hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

if (hWnd)
{
EMRGenericDialogBox(hWnd, hInstance, __argv[1], 1);
}


return FALSE;
}


EMRGenericDialogBox function is defined like as shown below:


void CALLBACK EMRGenericDialogBox(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
{
DLGPROC tmpProc = NULL;
DWORD dwShutdownDialog(0);
DWORD resourceID(0);
HANDLE hMutex = NULL;
g_Inst = hinst;

//Get the current operating system
OS_VERSION osVersion = EMRWindowsVersion::GetOperatingSystemVerson();

//Create the Resource dll object.

Resource emrResourceDLL(EMR_DALI_DEFAULT_REG_PATH, EMR_INSTALL_PATH);

//We do not want to diaplay any dialogs if we are currently shutting down the OS

RegistryObj regObj(EMR_DALI_SHUTDOWN_REG_PATH);

//We don't want to display a dialog if we are shutting down.

if (regObj.Get(EMR_SHUTDOWN_DIALOG, dwShutdownDialog))
{

//If dwShutdownDialog is true then one of the shutdown dialog is currently running.

if (dwShutdownDialog == 0)
{

if (lpszCmdLine)
{

if (_tcscmp(lpszCmdLine, EMR_HIBERNATION_DISABLED_DIALOG) == 0)
{
//Hibernation Disabled
tmpProc = Hibernation_Disabled_Proc;

resourceID = IDD_HIBERNATION_DISABLED;

CREATE_EMR_MUTEX(EMR_HIBERNATION_DISABLED_DIALOG);
}
else if (_tcscmp(lpszCmdLine, EMR_OVERLOAD_DIALOG) == 0)
{
//Overloaded dialog.

tmpProc = Overloaded_Battery_Disconnected_Proc;

resourceID = IDD_OVERLOADED;

CREATE_EMR_MUTEX(EMR_OVERLOAD_DIALOG);
}
else if (_tcscmp(lpszCmdLine, EMR_NO_COMMS_ON_INSTALL_DIALOG) == 0)
{
tmpProc = NoComm_Install_Proc;

resourceID = IDD_NOCOMMS_ON_INSTALL;

CREATE_EMR_MUTEX(EMR_NO_COMMS_ON_INSTALL_DIALOG);
}
else if (_tcscmp(lpszCmdLine, EMR_NO_COMMS_ON_UNINSTALL_DIALOG) == 0)
{
tmpProc = NoComm_Install_Proc;

resourceID = IDD_NOCOMMS_ON_UNINSTALL;

CREATE_EMR_MUTEX(EMR_NO_COMMS_ON_UNINSTALL_DIALOG);
}
else
{
assert("EMRGenericDialogBox()" == NULL);

}

if (tmpProc)
{
DWORD dwResult(0);

//Launch the dialog

if (!emrResourceDLL.loadDialog(resourceID, hwnd, tmpProc, dwResult))
{
//Unable to lanuch dialog, display error information.

TCHAR szMsg[MAX_PATH];

_tcscpy(szMsg,EMR_MSG_DLL_ERROR_MESSAGE);

MessageBox(NULL, szMsg, EMR_MSG_DLL_PRODUCT_NAME, NULL);
}

}

}

if (hMutex)
{
ReleaseMutex(hMutex);
CloseHandle(hMutex);
hMutex = NULL;
}


if (NULL != pExecuteProgram)
{
pExecuteProgram->Release ();
pExecuteProgram = NULL;
}
}

}

}

CREATE_EMR_MUTEX is defined like as shown below:


#define CREATE_EMR_MUTEX(MUTEX_NAME) SetLastError(0);
hMutex = CreateMutex(NULL, TRUE, MUTEX_NAME);
if ((GetLastError() == ERROR_ALREADY_EXISTS) || (hMutex == NULL)){
ReleaseMutex(0);
CloseHandle(hMutex);
hMutex = NULL;
return;}


#define EMR_NoComm_Install_Proc TEXT("E1D55521-E19C-11d5-BFCC-00B0D08A7991")

Below is the NoComm_Install_Proc function:

BOOL CALLBACK NoComm_Install_Proc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
BOOL bRetValue = FALSE;
BOOL bRetry = FALSE;

BringWindowToTop(hwndDlg);

RegistryObj regObj(APC_DALI_DIALOG_REG_PATH, HKEY_CURRENT_USER);
switch (message)
{
case WM_INITDIALOG:
ApcDialogBeep();
InitbackgroundBitmap(hwndDlg);
break;

case WM_CLOSE:
EndDialog(hwndDlg, wParam);
break;

case WM_DESTROY:
PostQuitMessage(0);
return 0;

case WM_COMMAND:

switch (LOWORD(wParam))
{
case ID_NPM_OK:
bRetry = TRUE;
regObj.Set(APC_DIALOG_NOCOMM_INSTALL_PATH, 1);
EndDialog(hwndDlg, wParam);
break;
case ID_NPM_CANCEL:
regObj.Set(APC_DIALOG_NOCOMM_INSTALL_PATH, 0);
EndDialog(hwndDlg, wParam);
break;
}
}

return bRetValue;
}

Thank you in advance,

Sankar



Y A S Prakash

Continue reading...
 
Back
Top