TapiCode.C
资源名称:tapisamp.rar [点击查看]
上传用户:woweijixie
上传日期:2018-12-11
资源大小:131k
文件大小:146k
源码类别:
TAPI编程
开发平台:
Visual C++
- if (HandleLineErr(lReturn))
- continue;
- else
- {
- OutputDebugLineError(lReturn,
- "lineGetDevCaps unhandled error: ");
- LocalFree(lpLineDevCaps);
- return NULL;
- }
- }
- while (lReturn != SUCCESS);
- // If the buffer was big enough, then succeed.
- if ((lpLineDevCaps -> dwNeededSize) <= (lpLineDevCaps -> dwTotalSize))
- return lpLineDevCaps;
- // Buffer wasn't big enough. Make it bigger and try again.
- sizeofLineDevCaps = lpLineDevCaps -> dwNeededSize;
- }
- }
- //
- // FUNCTION: I_lineGetAddressStatus(LPLINEADDRESSSTATUS, HLINE, DWORD)
- //
- // PURPOSE: Retrieve a LINEADDRESSSTATUS structure for the specified line.
- //
- // PARAMETERS:
- // lpLineAddressStatus - Pointer to a LINEADDRESSSTATUS structure to use.
- // hLine - Handle of line to get the AddressStatus of.
- // dwAddressID - Address ID on the hLine to be used.
- //
- // RETURN VALUE:
- // Returns a pointer to a LINEADDRESSSTATUS structure if successful.
- // Returns NULL if unsuccessful.
- //
- // COMMENTS:
- //
- // This function is a wrapper around lineGetAddressStatus to make it easy
- // to handle the variable sized structure and any errors received.
- //
- // The returned structure has been allocated with LocalAlloc,
- // so LocalFree has to be called on it when you're finished with it,
- // or there will be a memory leak.
- //
- // Similarly, if a lpLineAddressStatus structure is passed in, it *must*
- // have been allocated with LocalAlloc and it could potentially be
- // LocalFree()d.
- //
- // If lpLineAddressStatus == NULL, then a new structure is allocated. It
- // is normal to pass in NULL for this parameter unless you want to use a
- // lpLineAddressStatus that has been returned by previous
- // I_lineGetAddressStatus call.
- //
- //
- LPLINEADDRESSSTATUS I_lineGetAddressStatus(
- LPLINEADDRESSSTATUS lpLineAddressStatus,
- HLINE hLine, DWORD dwAddressID)
- {
- size_t sizeofLineAddressStatus = sizeof(LINEADDRESSSTATUS) + 1024;
- long lReturn;
- // Continue this loop until the structure is big enough.
- while(TRUE)
- {
- // Make sure the buffer exists, is valid and big enough.
- lpLineAddressStatus =
- (LPLINEADDRESSSTATUS) CheckAndReAllocBuffer(
- (LPVOID) lpLineAddressStatus,
- sizeofLineAddressStatus,
- "lineGetAddressStatus");
- if (lpLineAddressStatus == NULL)
- return NULL;
- // Make the call to fill the structure.
- do
- {
- lReturn =
- lineGetAddressStatus(hLine, dwAddressID, lpLineAddressStatus);
- if (HandleLineErr(lReturn))
- continue;
- else
- {
- OutputDebugLineError(lReturn,
- "lineGetAddressStatus unhandled error: ");
- LocalFree(lpLineAddressStatus);
- return NULL;
- }
- }
- while (lReturn != SUCCESS);
- // If the buffer was big enough, then succeed.
- if ((lpLineAddressStatus -> dwNeededSize) <=
- (lpLineAddressStatus -> dwTotalSize))
- {
- return lpLineAddressStatus;
- }
- // Buffer wasn't big enough. Make it bigger and try again.
- sizeofLineAddressStatus = lpLineAddressStatus -> dwNeededSize;
- }
- }
- //
- // FUNCTION: I_lineGetCallStatus(LPLINECALLSTATUS, HCALL)
- //
- // PURPOSE: Retrieve a LINECALLSTATUS structure for the specified line.
- //
- // PARAMETERS:
- // lpLineCallStatus - Pointer to a LINECALLSTATUS structure to use.
- // hCall - Handle of call to get the CallStatus of.
- //
- // RETURN VALUE:
- // Returns a pointer to a LINECALLSTATUS structure if successful.
- // Returns NULL if unsuccessful.
- //
- // COMMENTS:
- //
- // This function is a wrapper around lineGetCallStatus to make it easy
- // to handle the variable sized structure and any errors received.
- //
- // The returned structure has been allocated with LocalAlloc,
- // so LocalFree has to be called on it when you're finished with it,
- // or there will be a memory leak.
- //
- // Similarly, if a lpLineCallStatus structure is passed in, it *must*
- // have been allocated with LocalAlloc and it could potentially be
- // LocalFree()d.
- //
- // If lpLineCallStatus == NULL, then a new structure is allocated. It
- // is normal to pass in NULL for this parameter unless you want to use a
- // lpLineCallStatus that has been returned by previous I_lineGetCallStatus
- // call.
- //
- //
- LPLINECALLSTATUS I_lineGetCallStatus(
- LPLINECALLSTATUS lpLineCallStatus,
- HCALL hCall)
- {
- size_t sizeofLineCallStatus = sizeof(LINECALLSTATUS) + 1024;
- long lReturn;
- // Continue this loop until the structure is big enough.
- while(TRUE)
- {
- // Make sure the buffer exists, is valid and big enough.
- lpLineCallStatus =
- (LPLINECALLSTATUS) CheckAndReAllocBuffer(
- (LPVOID) lpLineCallStatus,
- sizeofLineCallStatus,
- "lineGetCallStatus");
- if (lpLineCallStatus == NULL)
- return NULL;
- // Make the call to fill the structure.
- do
- {
- lReturn =
- lineGetCallStatus(hCall, lpLineCallStatus);
- if (HandleLineErr(lReturn))
- continue;
- else
- {
- OutputDebugLineError(lReturn,
- "lineGetCallStatus unhandled error: ");
- LocalFree(lpLineCallStatus);
- return NULL;
- }
- }
- while (lReturn != SUCCESS);
- // If the buffer was big enough, then succeed.
- if ((lpLineCallStatus -> dwNeededSize) <=
- (lpLineCallStatus -> dwTotalSize))
- {
- return lpLineCallStatus;
- }
- // Buffer wasn't big enough. Make it bigger and try again.
- sizeofLineCallStatus = lpLineCallStatus -> dwNeededSize;
- }
- }
- //
- // FUNCTION: I_lineTranslateAddress
- // (LPLINETRANSLATEOUTPUT, DWORD, DWORD, LPCSTR)
- //
- // PURPOSE: Retrieve a LINECALLSTATUS structure for the specified line.
- //
- // PARAMETERS:
- // lpLineTranslateOutput - Pointer to a LINETRANSLATEOUTPUT structure.
- // dwDeviceID - Device that we're translating for.
- // dwAPIVersion - API Version to use.
- // lpszDialAddress - pointer to the DialAddress string to translate.
- //
- // RETURN VALUE:
- // Returns a pointer to a LINETRANSLATEOUTPUT structure if successful.
- // Returns NULL if unsuccessful.
- //
- // COMMENTS:
- //
- // This function is a wrapper around lineGetTranslateOutput to make it
- // easy to handle the variable sized structure and any errors received.
- //
- // The returned structure has been allocated with LocalAlloc,
- // so LocalFree has to be called on it when you're finished with it,
- // or there will be a memory leak.
- //
- // Similarly, if a lpLineTranslateOutput structure is passed in, it
- // *must* have been allocated with LocalAlloc and it could potentially be
- // LocalFree()d.
- //
- // If lpLineTranslateOutput == NULL, then a new structure is allocated.
- // It is normal to pass in NULL for this parameter unless you want to use
- // a lpLineTranslateOutput that has been returned by previous
- // I_lineTranslateOutput call.
- //
- //
- LPLINETRANSLATEOUTPUT I_lineTranslateAddress(
- LPLINETRANSLATEOUTPUT lpLineTranslateOutput,
- DWORD dwDeviceID, DWORD dwAPIVersion,
- LPCSTR lpszDialAddress)
- {
- size_t sizeofLineTranslateOutput = sizeof(LINETRANSLATEOUTPUT) + 1024;
- long lReturn;
- // Continue this loop until the structure is big enough.
- while(TRUE)
- {
- // Make sure the buffer exists, is valid and big enough.
- lpLineTranslateOutput =
- (LPLINETRANSLATEOUTPUT) CheckAndReAllocBuffer(
- (LPVOID) lpLineTranslateOutput,
- sizeofLineTranslateOutput,
- "lineTranslateOutput");
- if (lpLineTranslateOutput == NULL)
- return NULL;
- // Make the call to fill the structure.
- do
- {
- // Note that CALLWAITING is disabled
- // (assuming the service provider can disable it)
- lReturn =
- lineTranslateAddress(g_hLineApp, dwDeviceID, dwAPIVersion,
- lpszDialAddress, 0,
- LINETRANSLATEOPTION_CANCELCALLWAITING,
- lpLineTranslateOutput);
- // If the address isn't translatable, notify the user.
- if (lReturn == LINEERR_INVALADDRESS)
- MessageBox(g_hDlgParentWindow,
- "Unable to translate phone number","Warning",MB_OK);
- if (HandleLineErr(lReturn))
- continue;
- else
- {
- OutputDebugLineError(lReturn,
- "lineTranslateOutput unhandled error: ");
- LocalFree(lpLineTranslateOutput);
- return NULL;
- }
- }
- while (lReturn != SUCCESS);
- // If the buffer was big enough, then succeed.
- if ((lpLineTranslateOutput -> dwNeededSize) <=
- (lpLineTranslateOutput -> dwTotalSize))
- {
- return lpLineTranslateOutput;
- }
- // Buffer wasn't big enough. Make it bigger and try again.
- sizeofLineTranslateOutput = lpLineTranslateOutput -> dwNeededSize;
- }
- }
- //
- // FUNCTION: I_lineGetAddressCaps(LPLINEADDRESSCAPS, ..)
- //
- // PURPOSE: Retrieve a LINEADDRESSCAPS structure for the specified line.
- //
- // PARAMETERS:
- // lpLineAddressCaps - Pointer to a LINEADDRESSCAPS, or NULL.
- // dwDeviceID - Device to get the address caps for.
- // dwAddressID - This sample always assumes the first address.
- // dwAPIVersion - API version negotiated for the device.
- // dwExtVersion - Always 0 for this sample.
- //
- // RETURN VALUE:
- // Returns a pointer to a LINEADDRESSCAPS structure if successful.
- // Returns NULL if unsuccessful.
- //
- // COMMENTS:
- //
- // This function is a wrapper around lineGetAddressCaps to make it easy
- // to handle the variable sized structure and any errors received.
- //
- // The returned structure has been allocated with LocalAlloc,
- // so LocalFree has to be called on it when you're finished with it,
- // or there will be a memory leak.
- //
- // Similarly, if a lpLineAddressCaps structure is passed in, it *must*
- // have been allocated with LocalAlloc and it could potentially be
- // LocalFree()d. It also *must* have the dwTotalSize field set.
- //
- // If lpLineAddressCaps == NULL, then a new structure is allocated. It
- // is normal to pass in NULL for this parameter unless you want to use a
- // lpLineCallStatus that has been returned by previous I_lineGetAddressCaps
- // call.
- //
- //
- LPLINEADDRESSCAPS I_lineGetAddressCaps (
- LPLINEADDRESSCAPS lpLineAddressCaps,
- DWORD dwDeviceID, DWORD dwAddressID,
- DWORD dwAPIVersion, DWORD dwExtVersion)
- {
- size_t sizeofLineAddressCaps = sizeof(LINEADDRESSCAPS) + 1024;
- long lReturn;
- // Continue this loop until the structure is big enough.
- while(TRUE)
- {
- // Make sure the buffer exists, is valid and big enough.
- lpLineAddressCaps =
- (LPLINEADDRESSCAPS) CheckAndReAllocBuffer(
- (LPVOID) lpLineAddressCaps,
- sizeofLineAddressCaps,
- "lineGetAddressCaps");
- if (lpLineAddressCaps == NULL)
- return NULL;
- // Make the call to fill the structure.
- do
- {
- lReturn =
- lineGetAddressCaps(g_hLineApp,
- dwDeviceID, dwAddressID, dwAPIVersion, dwExtVersion,
- lpLineAddressCaps);
- if (HandleLineErr(lReturn))
- continue;
- else
- {
- OutputDebugLineError(lReturn,
- "lineGetAddressCaps unhandled error: ");
- LocalFree(lpLineAddressCaps);
- return NULL;
- }
- }
- while (lReturn != SUCCESS);
- // If the buffer was big enough, then succeed.
- if ((lpLineAddressCaps -> dwNeededSize) <=
- (lpLineAddressCaps -> dwTotalSize))
- {
- return lpLineAddressCaps;
- }
- // Buffer wasn't big enough. Make it bigger and try again.
- sizeofLineAddressCaps = lpLineAddressCaps -> dwNeededSize;
- }
- }
- //**************************************************
- // LINEERR Error Handlers
- //**************************************************
- //
- // FUNCTION: HandleLineErr(long)
- //
- // PURPOSE: Handle several standard LINEERR errors
- //
- // PARAMETERS:
- // lLineErr - Error code to be handled.
- //
- // RETURN VALUE:
- // Return TRUE if lLineErr wasn't an error, or if the
- // error was successfully handled and cleared up.
- // Return FALSE if lLineErr was an unhandled error.
- //
- // COMMENTS:
- //
- // This is the main error handler for all TAPI line APIs.
- // It handles (by correcting or just notifying the user)
- // most of the errors that can occur while using TAPI line APIs.
- //
- // Note that many errors still return FALSE (unhandled) even
- // if a dialog is displayed. Often, the dialog is just notifying
- // the user why the action was canceled.
- //
- //
- //
- BOOL HandleLineErr(long lLineErr)
- {
- // lLineErr is really an async request ID, not an error.
- if (lLineErr > SUCCESS)
- return FALSE;
- // All we do is dispatch the correct error handler.
- switch(lLineErr)
- {
- case SUCCESS:
- return TRUE;
- case LINEERR_INVALCARD:
- case LINEERR_INVALLOCATION:
- case LINEERR_INIFILECORRUPT:
- return HandleIniFileCorrupt();
- case LINEERR_NODRIVER:
- return HandleNoDriver();
- case LINEERR_REINIT:
- return HandleReInit();
- case LINEERR_NOMULTIPLEINSTANCE:
- return HandleNoMultipleInstance();
- case LINEERR_NOMEM:
- return HandleNoMem();
- case LINEERR_OPERATIONFAILED:
- return HandleOperationFailed();
- case LINEERR_RESOURCEUNAVAIL:
- return HandleResourceUnavail();
- // Unhandled errors fail.
- default:
- return FALSE;
- }
- }
- //
- // FUNCTION: HandleIniFileCorrupt
- //
- // PURPOSE: Handle INIFILECORRUPT error.
- //
- // PARAMETERS:
- // none
- //
- // RETURN VALUE:
- // TRUE - error was corrected.
- // FALSE - error was not corrected.
- //
- // COMMENTS:
- //
- // This error shouldn't happen under Windows 95 anymore. The TAPI.DLL
- // takes care of correcting this problem. If it does happen, just
- // notify the user.
- //
- BOOL HandleIniFileCorrupt()
- {
- if (IDCANCEL == MessageBox(g_hDlgParentWindow,
- "Configuration information relating to Telephony "
- "services appears to be corrupt.n"
- "This could be the first time you have used the Telephony services.n"
- "Would you like to configure the Telephony services?",
- "Warning",MB_OKCANCEL))
- {
- return FALSE;
- }
- lineTranslateDialog(g_hLineApp, 0, SAMPLE_TAPI_VERSION,
- g_hDlgParentWindow, NULL);
- return TRUE;
- }
- //
- // FUNCTION: HandleNoDriver
- //
- // PURPOSE: Handle NODRIVER error.
- //
- // PARAMETERS:
- // none
- //
- // RETURN VALUE:
- // TRUE - error was corrected.
- // FALSE - error was not corrected.
- //
- // COMMENTS:
- //
- //
- BOOL HandleNoDriver()
- {
- int mbRet;
- mbRet = MessageBox(g_hDlgParentWindow,
- "One of the components of the Telephony device driver is missing.n"
- "Use the Control Panel to set up the driver properly.",
- "Warning",MB_OK);
- return FALSE;
- }
- //
- // FUNCTION: HandleNoMultipleInstance
- //
- // PURPOSE: Handle NOMULTIPLEINSTANCE error.
- //
- // PARAMETERS:
- // none
- //
- // RETURN VALUE:
- // TRUE - error was corrected.
- // FALSE - error was not corrected.
- //
- // COMMENTS:
- //
- //
- BOOL HandleNoMultipleInstance()
- {
- MessageBox(g_hDlgParentWindow,
- "You have two copies of the same Telephony driver installed.n"
- "Use the Control Panel to remove one of the copies.",
- "Warning",MB_OK);
- return FALSE;
- }
- //
- // FUNCTION: HandleReInit
- //
- // PURPOSE: Handle REINIT error.
- //
- // PARAMETERS:
- // none
- //
- // RETURN VALUE:
- // TRUE - error was corrected.
- // FALSE - error was not corrected.
- //
- // COMMENTS:
- //
- //
- BOOL HandleReInit()
- {
- ShutdownTAPI();
- return FALSE;
- }
- //
- // FUNCTION: HandleNoMem
- //
- // PURPOSE: Handle NOMEM error.
- //
- // PARAMETERS:
- // none
- //
- // RETURN VALUE:
- // TRUE - error was corrected.
- // FALSE - error was not corrected.
- //
- // COMMENTS:
- // This is also called if I run out of memory for LocalAlloc()s
- //
- //
- BOOL HandleNoMem()
- {
- MessageBox(g_hDlgParentWindow,
- "Out of Memory error, canceling action.","Error", MB_OK);
- return FALSE;
- }
- //
- // FUNCTION: HandleOperationFailed
- //
- // PURPOSE: Handle OPERATIONFAILED error.
- //
- // PARAMETERS:
- // none
- //
- // RETURN VALUE:
- // TRUE - error was corrected.
- // FALSE - error was not corrected.
- //
- // COMMENTS:
- //
- //
- BOOL HandleOperationFailed()
- {
- MessageBox(g_hDlgParentWindow,
- "TAPI Operation Failed for unknown reasons.",
- "Error", MB_OK);
- return FALSE;
- }
- //
- // FUNCTION: HandleResourceUnavail
- //
- // PURPOSE: Handle RESOURCEUNAVAIL error.
- //
- // PARAMETERS:
- // none
- //
- // RETURN VALUE:
- // TRUE - error was corrected.
- // FALSE - error was not corrected.
- //
- // COMMENTS:
- //
- //
- BOOL HandleResourceUnavail()
- {
- int mbRet;
- mbRet = MessageBox(g_hDlgParentWindow,
- "A Telephony resource is temporarily unavaiable. "
- "This could mean a short wait is necessary or "
- "that a non-TAPI application is using the line.",
- "Warning",MB_RETRYCANCEL);
- if (mbRet == IDRETRY)
- return TRUE;
- return FALSE;
- }
- //
- // FUNCTION: HandleNoDevicesInstalled
- //
- // PURPOSE: Handle cases when we know NODEVICE error
- // is returned because there are no devices installed.
- //
- // PARAMETERS:
- // none
- //
- // RETURN VALUE:
- // TRUE - error was corrected.
- // FALSE - error was not corrected.
- //
- // COMMENTS:
- //
- // This function is not part of standard error handling
- // but is only used when we know that the NODEVICE error
- // means that no devices are installed.
- //
- //
- BOOL HandleNoDevicesInstalled()
- {
- int mbRet;
- mbRet = MessageBox(g_hDlgParentWindow,
- "There are no devices configured for Telephony use.n"
- "Would you like to run the Modem Control Panel to add a modem driver?",
- "Warning",MB_YESNO);
- if (mbRet == IDYES)
- {
- if (LaunchModemControlPanelAdd())
- return TRUE;
- }
- return FALSE;
- }
- //
- // FUNCTION: LaunchModemControlPanelAdd
- //
- // PURPOSE: Launch Add Modem Control Panel applet.
- //
- // PARAMETERS:
- // none
- //
- // RETURN VALUE:
- // TRUE - Control Panel launched successfully.
- // FALSE - It didn't.
- //
- // COMMENTS:
- //
- //
- BOOL LaunchModemControlPanelAdd()
- {
- PROCESS_INFORMATION piProcInfo;
- STARTUPINFO siStartupInfo;
- siStartupInfo.cb = sizeof(STARTUPINFO);
- siStartupInfo.lpReserved = NULL;
- siStartupInfo.lpDesktop = NULL;
- siStartupInfo.lpTitle = NULL;
- siStartupInfo.dwFlags = STARTF_USESHOWWINDOW;
- siStartupInfo.wShowWindow = SW_SHOWNORMAL;
- siStartupInfo.cbReserved2 = 0;
- siStartupInfo.lpReserved2 = NULL;
- // The string to launch the modem control panel is *VERY* likely
- // to change on NT. If nothing else, this is 'contrl32' on NT
- // instead of 'control'.
- if (CreateProcess(
- NULL,
- "CONTROL.EXE MODEM.CPL,,ADD",
- NULL, NULL, FALSE,
- NORMAL_PRIORITY_CLASS,
- NULL, NULL,
- &siStartupInfo,
- &piProcInfo))
- {
- CloseHandle(piProcInfo.hThread);
- // Control panel 'Add New Modem' has been launched. Now we should
- // wait for it to go away before continueing.
- // If we WaitForSingleObject for the control panel to exit, then we
- // get into a deadlock situation if we need to respond to any messages
- // from the control panel.
- // If we use a PeekMessage loop to wait, we run into
- // message re-entrancy problems. (The user can get back to our UI
- // and click 'dial' again).
- // Instead, we take the easy way out and return FALSE to abort
- // the current operation.
- CloseHandle(piProcInfo.hProcess);
- }
- else
- {
- OutputDebugLastError(GetLastError(),
- "Unable to LaunchModemControlPanelAdd: ");
- MessageBox(g_hDlgParentWindow,
- "Unable to launch the Modem Control Panel",
- "Warning", MB_OK);
- }
- return FALSE;
- }
- //
- // FUNCTION: WarningBox(LPCSTR)
- //
- // PURPOSE: Prints a warning box when conditions remove a line in use.
- //
- // PARAMETERS:
- // lpszMessage - String that specifies why the line was removed form use.
- //
- // RETURN VALUE:
- // none
- //
- // COMMENTS:
- //
- // If there is a call in progress on the line removed, then display a message
- // specifying why the line was removed and that the call is being canceled.
- //
- //
- void WarningBox(LPCSTR lpszMessage)
- {
- char szBuff[1024];
- strcpy(szBuff, lpszMessage);
- // If there is a call open, tell user we're going to close it.
- if (g_hCall)
- strcat(szBuff, "nClosing existing call.");
- MessageBox(g_hDlgParentWindow, szBuff, "Warning", MB_OK);
- strcat(szBuff, "rn");
- OutputDebugString(szBuff);
- }
- //**************************************************
- //
- // All the functions from this point on are used solely by the "Dial" dialog.
- // This dialog is used to get both the 'phone number' address,
- // the line device to be used as well as allow the user to configure
- // dialing properties and the line device.
- //
- //**************************************************
- //
- // FUNCTION: DWORD I_lineNegotiateLegacyAPIVersion(DWORD)
- //
- // PURPOSE: Negotiate an API Version to use for a specific device.
- //
- // PARAMETERS:
- // dwDeviceID - device to negotiate an API Version for.
- //
- // RETURN VALUE:
- // Returns the API Version to use for this line if successful.
- // Returns 0 if negotiations fall through.
- //
- // COMMENTS:
- //
- // This wrapper is slightly different from the I_lineNegotiateAPIVersion.
- // This wrapper allows TapiComm to negotiate an API version between
- // 1.3 and SAMPLE_TAPI_VERSION. Normally, this sample is specific to
- // API Version SAMPLE_TAPI_VERSION. However, there are a few times when
- // TapiComm needs to get information from a service provider, but also knows
- // that a lower API Version would be ok. This allows TapiComm to recognize
- // legacy service providers even though it can't use them. 1.3 is the
- // lowest API Version a legacy service provider should support.
- //
- //
- DWORD I_lineNegotiateLegacyAPIVersion(DWORD dwDeviceID)
- {
- LINEEXTENSIONID LineExtensionID;
- long lReturn;
- DWORD dwLocalAPIVersion;
- do
- {
- lReturn = lineNegotiateAPIVersion(g_hLineApp, dwDeviceID,
- 0x00010003, SAMPLE_TAPI_VERSION,
- &dwLocalAPIVersion, &LineExtensionID);
- if (lReturn == LINEERR_INCOMPATIBLEAPIVERSION)
- {
- OutputDebugString("INCOMPATIBLEAPIVERSION in Dial Dialog.n");
- return 0;
- }
- if (HandleLineErr(lReturn))
- continue;
- else
- {
- OutputDebugLineError(lReturn,
- "lineNegotiateAPIVersion in Dial Dialog unhandled error: ");
- return 0;
- }
- }
- while(lReturn != SUCCESS);
- return dwLocalAPIVersion;
- }
- //
- // FUNCTION: long VerifyUsableLine(DWORD)
- //
- // PURPOSE: Verifies that a specific line device is useable by TapiComm.
- //
- // PARAMETERS:
- // dwDeviceID - The ID of the line device to be verified
- //
- // RETURN VALUE:
- // Returns SUCCESS if dwDeviceID is a usable line device.
- // Returns a LINENOTUSEABLE_ constant otherwise.
- //
- // COMMENTS:
- //
- // VerifyUsableLine takes the give device ID and verifies step by step
- // that the device supports all the features that TapiComm requires.
- //
- //
- long VerifyUsableLine(DWORD dwDeviceID)
- {
- LPLINEDEVCAPS lpLineDevCaps = NULL;
- LPLINEADDRESSSTATUS lpLineAddressStatus = NULL;
- LPVARSTRING lpVarString = NULL;
- DWORD dwAPIVersion;
- long lReturn;
- long lUsableLine = SUCCESS;
- HLINE hLine = 0;
- OutputDebugPrintf("Testing Line ID '0x%lx'",dwDeviceID);
- // The line device must support an API Version that TapiComm does.
- dwAPIVersion = I_lineNegotiateAPIVersion(dwDeviceID);
- if (dwAPIVersion == 0)
- return LINENOTUSEABLE_ERROR;
- lpLineDevCaps = I_lineGetDevCaps(lpLineDevCaps,
- dwDeviceID, dwAPIVersion);
- if (lpLineDevCaps == NULL)
- return LINENOTUSEABLE_ERROR;
- // Must support LINEBEARERMODE_VOICE
- if (!(lpLineDevCaps->dwBearerModes & LINEBEARERMODE_VOICE ))
- {
- lUsableLine = LINENOTUSEABLE_NOVOICE;
- OutputDebugString("LINEBEARERMODE_VOICE not supportedn");
- goto DeleteBuffers;
- }
- // Must support LINEMEDIAMODE_DATAMODEM
- if (!(lpLineDevCaps->dwMediaModes & LINEMEDIAMODE_DATAMODEM))
- {
- lUsableLine = LINENOTUSEABLE_NODATAMODEM;
- OutputDebugString("LINEMEDIAMODE_DATAMODEM not supportedn");
- goto DeleteBuffers;
- }
- // Must be able to make calls
- if (!(lpLineDevCaps->dwLineFeatures & LINEFEATURE_MAKECALL))
- {
- lUsableLine = LINENOTUSEABLE_NOMAKECALL;
- OutputDebugString("LINEFEATURE_MAKECALL not supportedn");
- goto DeleteBuffers;
- }
- // It is necessary to open the line so we can check if
- // there are any call appearances available. Other TAPI
- // applications could be using all call appearances.
- // Opening the line also checks for other possible problems.
- do
- {
- lReturn = lineOpen(g_hLineApp, dwDeviceID, &hLine,
- dwAPIVersion, 0, 0,
- LINECALLPRIVILEGE_NONE, LINEMEDIAMODE_DATAMODEM,
- 0);
- if(lReturn == LINEERR_ALLOCATED)
- {
- OutputDebugString(
- "Line is already in use by a non-TAPI app or"
- " another Service Provider.n");
- lUsableLine = LINENOTUSEABLE_ALLOCATED;
- goto DeleteBuffers;
- }
- if (HandleLineErr(lReturn))
- continue;
- else
- {
- OutputDebugLineError(lReturn, "lineOpen unhandled error: ");
- lUsableLine = LINENOTUSEABLE_ERROR;
- goto DeleteBuffers;
- }
- }
- while(lReturn != SUCCESS);
- // Get LineAddressStatus to make sure the line isn't already in use.
- lpLineAddressStatus =
- I_lineGetAddressStatus(lpLineAddressStatus, hLine, 0);
- if (lpLineAddressStatus == NULL)
- {
- lUsableLine = LINENOTUSEABLE_ERROR;
- goto DeleteBuffers;
- }
- // Are there any available call appearances (ie: is it in use)?
- if ( !((lpLineAddressStatus -> dwAddressFeatures) &
- LINEADDRFEATURE_MAKECALL) )
- {
- OutputDebugString("LINEADDRFEATURE_MAKECALL not availablen");
- lUsableLine = LINENOTUSEABLE_INUSE;
- goto DeleteBuffers;
- }
- // Make sure the "comm/datamodem" device class is supported
- // Note that we don't want any of the 'extra' information
- // normally returned in the VARSTRING structure. All we care
- // about is if lineGetID succeeds.
- do
- {
- lpVarString = CheckAndReAllocBuffer((LPVOID) lpVarString,
- sizeof(VARSTRING),"VerifyUsableLine:lineGetID: ");
- if (lpVarString == NULL)
- {
- lUsableLine = LINENOTUSEABLE_ERROR;
- goto DeleteBuffers;
- }
- lReturn = lineGetID(hLine, 0, 0, LINECALLSELECT_LINE,
- lpVarString, "comm/datamodem");
- if (HandleLineErr(lReturn))
- continue;
- else
- {
- OutputDebugLineError(lReturn,
- "lineGetID unhandled error: ");
- lUsableLine = LINENOTUSEABLE_NOCOMMDATAMODEM;
- goto DeleteBuffers;
- }
- }
- while(lReturn != SUCCESS);
- OutputDebugString("Line is suitable and available for use.n");
- DeleteBuffers:
- if (hLine)
- lineClose(hLine);
- if (lpLineAddressStatus)
- LocalFree(lpLineAddressStatus);
- if (lpLineDevCaps)
- LocalFree(lpLineDevCaps);
- if (lpVarString)
- LocalFree(lpVarString);
- return lUsableLine;
- }
- //
- // FUNCTION: void FillTAPILine(HWND)
- //
- // PURPOSE: Fills the 'TAPI Line' control with the available line devices.
- //
- // PARAMETERS:
- // hwndDlg - handle to the current "Dial" dialog
- //
- // RETURN VALUE:
- // none
- //
- // COMMENTS:
- //
- // This function enumerates through all the TAPI line devices and
- // queries each for the device name. The device name is then put into
- // the 'TAPI Line' control. These device names are kept in order rather
- // than sorted. This allows "Dial" to know which device ID the user
- // selected just by the knowing the index of the selected string.
- //
- // There are default values if there isn't a device name, if there is
- // an error on the device, or if the device name is an empty string.
- // The device name is also checked to make sure it is null terminated.
- //
- // Note that a Legacy API Version is negotiated. Since the fields in
- // the LINEDEVCAPS structure that we are interested in haven't moved, we
- // can negotiate a lower API Version than this sample is designed for
- // and still be able to access the necessary structure members.
- //
- // The first line that is usable by TapiComm is selected as the 'default'
- // line. Also note that if there was a previously selected line, this
- // remains the default line. This would likely only occur if this
- // function is called after the dialog has initialized once; for example,
- // if a new line is added.
- //
- //
- void FillTAPILine(HWND hwndDlg)
- {
- DWORD dwDeviceID;
- DWORD dwAPIVersion;
- LPLINEDEVCAPS lpLineDevCaps = NULL;
- char szLineUnavail[] = "Line Unavailable";
- char szLineUnnamed[] = "Line Unnamed";
- char szLineNameEmpty[] = "Line Name is Empty";
- LPSTR lpszLineName;
- long lReturn;
- DWORD dwDefaultDevice = MAXDWORD;
- // Make sure the control is empty. If it isn't,
- // hold onto the currently selected ID and then reset it.
- if (SendDlgItemMessage(hwndDlg, IDC_TAPILINE, CB_GETCOUNT, 0, 0))
- {
- dwDefaultDevice = SendDlgItemMessage(hwndDlg, IDC_TAPILINE,
- CB_GETCURSEL, 0, 0);
- SendDlgItemMessage(hwndDlg, IDC_TAPILINE, CB_RESETCONTENT, 0, 0);
- }
- for (dwDeviceID = 0; dwDeviceID < g_dwNumDevs; dwDeviceID ++)
- {
- dwAPIVersion = I_lineNegotiateLegacyAPIVersion(dwDeviceID);
- if (dwAPIVersion)
- {
- lpLineDevCaps = I_lineGetDevCaps(lpLineDevCaps,
- dwDeviceID, dwAPIVersion);
- if (lpLineDevCaps)
- {
- if ((lpLineDevCaps -> dwLineNameSize) &&
- (lpLineDevCaps -> dwLineNameOffset) &&
- (lpLineDevCaps -> dwStringFormat == STRINGFORMAT_ASCII))
- {
- // This is the name of the device.
- lpszLineName = ((char *) lpLineDevCaps) +
- lpLineDevCaps -> dwLineNameOffset;
- if (lpszLineName[0] != ' ')
- {
- // Reverse indented to make this fit
- // Make sure the device name is null terminated.
- if (lpszLineName[lpLineDevCaps->dwLineNameSize -1] != ' ')
- {
- // If the device name is not null terminated, null
- // terminate it. Yes, this looses the end character.
- // Its a bug in the service provider.
- lpszLineName[lpLineDevCaps->dwLineNameSize-1] = ' ';
- OutputDebugPrintf(
- "Device name for device 0x%lx is not null terminated.n",
- dwDeviceID);
- }
- }
- else // Line name started with a NULL.
- lpszLineName = szLineNameEmpty;
- }
- else // DevCaps doesn't have a valid line name. Unnamed.
- lpszLineName = szLineUnnamed;
- }
- else // Couldn't GetDevCaps. Line is unavail.
- lpszLineName = szLineUnavail;
- }
- else // Couldn't NegotiateAPIVersion. Line is unavail.
- lpszLineName = szLineUnavail;
- // Put the device name into the control
- lReturn = SendDlgItemMessage(hwndDlg, IDC_TAPILINE,
- CB_ADDSTRING, 0, (LPARAM) (LPCTSTR) lpszLineName);
- // If this line is usable and we don't have a default initial
- // line yet, make this the initial line.
- if ((lpszLineName != szLineUnavail) &&
- (dwDefaultDevice == MAXDWORD) &&
- (VerifyUsableLine(dwDeviceID) == SUCCESS))
- {
- dwDefaultDevice = dwDeviceID;
- }
- }
- if (lpLineDevCaps)
- LocalFree(lpLineDevCaps);
- if (dwDefaultDevice == MAXDWORD)
- dwDefaultDevice = 0;
- // Set the initial default line
- SendDlgItemMessage(hwndDlg, IDC_TAPILINE,
- CB_SETCURSEL, dwDefaultDevice, 0);
- }
- //
- // FUNCTION: BOOL VerifyAndWarnUsableLine(HWND)
- //
- // PURPOSE: Verifies the line device selected by the user.
- //
- // PARAMETERS:
- // hwndDlg - The handle to the current "Dial" dialog.
- //
- // RETURN VALUE:
- // Returns TRUE if the currently selected line device is useable
- // by TapiComm. Returns FALSE if it isn't.
- //
- // COMMENTS:
- //
- // This function is very specific to the "Dial" dialog. It gets
- // the device selected by the user from the 'TAPI Line' control and
- // VerifyUsableLine to make sure this line device is usable. If the
- // line isn't useable, it notifies the user and disables the 'Dial'
- // button so that the user can't initiate a call with this line.
- //
- // This function is also responsible for filling in the line specific
- // icon found on the "Dial" dialog.
- //
- //
- BOOL VerifyAndWarnUsableLine(HWND hwndDlg)
- {
- DWORD dwDeviceID;
- long lReturn;
- HICON hIcon = 0;
- HWND hControlWnd;
- // Get the selected line device.
- dwDeviceID = SendDlgItemMessage(hwndDlg, IDC_TAPILINE,
- CB_GETCURSEL, 0, 0);
- // Get the "comm" device icon associated with this line device.
- lReturn = lineGetIcon(dwDeviceID, "comm", &hIcon);
- if (lReturn == SUCCESS)
- SendDlgItemMessage(hwndDlg, IDC_LINEICON, STM_SETICON,
- (WPARAM) hIcon, 0);
- else
- // Any failure to get an icon makes us use the default icon.
- SendDlgItemMessage(hwndDlg, IDC_LINEICON, WM_SETTEXT,
- 0, (LPARAM) (LPCTSTR) "TapiComm");
- /* // It turns out that TAPI will always return an icon, even if
- // the device class isn't supported by the TSP or even if the TSP
- // doesn't return any icons at all. This code is unnecessary.
- // The only reason lineGetIcon would fail is due to resource problems.
- else
- {
- // If the line doesn't have a "comm" device icon, use its default one.
- lReturn = lineGetIcon(dwDeviceID, NULL, &hIcon);
- if (lReturn == SUCCESS)
- {
- OutputDebugString("Line doesn't support a "comm" icon.n");
- SendDlgItemMessage(hwndDlg, IDC_LINEICON, STM_SETICON,
- (WPARAM) hIcon, 0);
- }
- else
- {
- // If lineGetIcon fails, just use TapiComms icon.
- OutputDebugLineError(lReturn, "lineGetIcon: ");
- SendDlgItemMessage(hwndDlg, IDC_LINEICON, WM_SETTEXT,
- 0, (LPARAM) (LPCTSTR) "TapiComm");
- }
- }
- */
- // Verify if the device is usable by TapiComm.
- lReturn = VerifyUsableLine(dwDeviceID);
- // Enable or disable the 'Dial' button, depending on if the line is ok.
- // Make sure there is a number to dial before enabling the button.
- hControlWnd = GetDlgItem(hwndDlg, IDC_DIAL);
- if (SendDlgItemMessage(hwndDlg, IDC_CANONICALNUMBER,
- WM_GETTEXTLENGTH, 0, 0) == 0)
- {
- EnableWindow(hControlWnd, FALSE);
- }
- else
- EnableWindow(hControlWnd, (lReturn == SUCCESS));
- // Any errors on this line prevent us from configuring it
- // or using dialing properties.
- if (lReturn == LINENOTUSEABLE_ERROR)
- {
- EnableWindow(GetDlgItem(hwndDlg, IDC_CONFIGURELINE), FALSE);
- EnableWindow(GetDlgItem(hwndDlg, IDC_DIALINGPROPERTIES), FALSE);
- }
- else
- {
- EnableWindow(GetDlgItem(hwndDlg, IDC_CONFIGURELINE), TRUE);
- if (SendDlgItemMessage(hwndDlg, IDC_USEDIALINGRULES, BM_GETCHECK, 0, 0))
- EnableWindow(GetDlgItem(hwndDlg, IDC_DIALINGPROPERTIES), TRUE);
- }
- switch(lReturn)
- {
- case SUCCESS:
- g_dwDeviceID = dwDeviceID;
- return TRUE;
- case LINENOTUSEABLE_ERROR:
- MessageBox(hwndDlg,
- "The selected line is incompatible with the TapiComm sample",
- "Warning",MB_OK);
- break;
- case LINENOTUSEABLE_NOVOICE:
- MessageBox(hwndDlg,
- "The selected line doesn't support VOICE capabilities",
- "Warning",MB_OK);
- break;
- case LINENOTUSEABLE_NODATAMODEM:
- MessageBox(hwndDlg,
- "The selected line doesn't support DATAMODEM capabilities",
- "Warning",MB_OK);
- break;
- case LINENOTUSEABLE_NOMAKECALL:
- MessageBox(hwndDlg,
- "The selected line doesn't support MAKECALL capabilities",
- "Warning",MB_OK);
- break;
- case LINENOTUSEABLE_ALLOCATED:
- MessageBox(hwndDlg,
- "The selected line is already in use by a non-TAPI application",
- "Warning",MB_OK);
- break;
- case LINENOTUSEABLE_INUSE:
- MessageBox(hwndDlg,
- "The selected line is already in use by a TAPI application",
- "Warning",MB_OK);
- break;
- case LINENOTUSEABLE_NOCOMMDATAMODEM:
- MessageBox(hwndDlg,
- "The selected line doesn't support the COMM/DATAMODEM device class",
- "Warning",MB_OK);
- break;
- }
- // g_dwDeviceID == MAXDWORD mean the selected device isn't usable.
- g_dwDeviceID = MAXDWORD;
- return FALSE;
- }
- //
- // FUNCTION: void FillCountryCodeList(HWND, DWORD)
- //
- // PURPOSE: Fill the 'Country Code' control
- //
- // PARAMETERS:
- // hwndDlg - handle to the current "Dial" dialog
- // dwDefaultCountryID - ID of the 'default' country to be selected
- //
- // RETURN VALUE:
- // none
- //
- // COMMENTS:
- //
- // This function fills the 'Country Code' control with country names.
- // The country code is appended to the end of the name and the names
- // are added to the control sorted. Because the country code is
- // embedded in the string along with the country name, there is no need
- // for any of the country information structures to be kept around. The
- // country code can be extracted from the selected string at any time.
- //
- //
- void FillCountryCodeList(HWND hwndDlg, DWORD dwDefaultCountryID)
- {
- LPLINECOUNTRYLIST lpLineCountryList = NULL;
- DWORD dwSizeofCountryList = sizeof(LINECOUNTRYLIST);
- long lReturn;
- DWORD dwCountry;
- LPLINECOUNTRYENTRY lpLineCountryEntries;
- char szRenamedCountry[256];
- // Get the country information stored in TAPI
- do
- {
- lpLineCountryList = (LPLINECOUNTRYLIST) CheckAndReAllocBuffer(
- (LPVOID) lpLineCountryList, dwSizeofCountryList,
- "FillCountryCodeList");
- if (lpLineCountryList == NULL)
- return;
- lReturn = lineGetCountry (0, SAMPLE_TAPI_VERSION, lpLineCountryList);
- if (HandleLineErr(lReturn))
- ;
- else
- {
- OutputDebugLineError(lReturn, "lineGetCountry unhandled error: ");
- LocalFree(lpLineCountryList);
- return;
- }
- if ((lpLineCountryList -> dwNeededSize) >
- (lpLineCountryList -> dwTotalSize))
- {
- dwSizeofCountryList = lpLineCountryList ->dwNeededSize;
- lReturn = -1; // Lets loop again.
- }
- }
- while (lReturn != SUCCESS);
- // Find the first country entry
- lpLineCountryEntries = (LPLINECOUNTRYENTRY)
- (((LPBYTE) lpLineCountryList)
- + lpLineCountryList -> dwCountryListOffset);
- // Now enumerate through all the countries
- for (dwCountry = 0;
- dwCountry < lpLineCountryList -> dwNumCountries;
- dwCountry++)
- {
- // append the country code to the country name
- wsprintf(szRenamedCountry,"%s (%lu)",
- (((LPSTR) lpLineCountryList) +
- lpLineCountryEntries[dwCountry].dwCountryNameOffset),
- lpLineCountryEntries[dwCountry].dwCountryCode);
- // Now put this country name / code string into the combobox
- lReturn = SendDlgItemMessage(hwndDlg, IDC_COUNTRYCODE, CB_ADDSTRING,
- 0, (LPARAM) (LPCTSTR) szRenamedCountry);
- // If this country is the default country, select it.
- if (lpLineCountryEntries[dwCountry].dwCountryID
- == dwDefaultCountryID)
- {
- SendDlgItemMessage(hwndDlg, IDC_COUNTRYCODE, CB_SETCURSEL, lReturn, 0);
- }
- }
- LocalFree(lpLineCountryList);
- return;
- }
- //
- // FUNCTION: void FillLocationInfo(HWND, LPSTR, LPDWORD, LPSTR)
- //
- // PURPOSE: Fill (or refill) the 'Your Location' control
- //
- // PARAMETERS:
- // hwndDlg - handle to the current "Dial" dialog
- // lpszCurrentLocation - Name of current location, or NULL
- // lpdwCountryID - location to store the current country ID or NULL
- // lpszAreaCode - location to store the current area code or NULL
- //
- // RETURN VALUE:
- // none
- //
- // COMMENTS:
- //
- // This function is moderately multipurpose.
- //
- // If lpszCurrentLocation is NULL, then the 'Your Location' control
- // is filled with all the locations stored in TAPI and the TAPI 'default'
- // location is selected. This is done during initialization and
- // also after the 'Dialing Properties' dialog has been displayed.
- // This last is done because the user can change the current location
- // or add and delete locations while in the 'Dialing Properties' dialog.
- //
- // If lpszCurrentLocation is a valid string pointer, then it is assumed
- // that the 'Your Location' control is already filled and that the user
- // is selecting a specific location. In this case, all of the existing
- // TAPI locations are enumerated until the specified location is found.
- // At this point, the specified location is set to the current location.
- //
- // In either case, if lpdwCountryID is not NULL, it is filled with the
- // country ID for the current location. If lpszAreaCode is not NULL, it
- // is filled with the area code defined for the current location. These
- // values can be used later to initialize other "Dial" controls.
- //
- // This function also fills the 'Calling Card' control based on
- // the information stored in the current location.
- //
- //
- void FillLocationInfo(HWND hwndDlg, LPSTR lpszCurrentLocation,
- LPDWORD lpdwCountryID, LPSTR lpszAreaCode)
- {
- LPLINETRANSLATECAPS lpTranslateCaps = NULL;
- DWORD dwSizeofTranslateCaps = sizeof(LINETRANSLATECAPS);
- long lReturn;
- DWORD dwCounter;
- LPLINELOCATIONENTRY lpLocationEntry;
- LPLINECARDENTRY lpLineCardEntry = NULL;
- DWORD dwPreferredCardID = MAXDWORD;
- // First, get the TRANSLATECAPS
- do
- {
- lpTranslateCaps = (LPLINETRANSLATECAPS) CheckAndReAllocBuffer(
- (LPVOID) lpTranslateCaps, dwSizeofTranslateCaps,
- "FillLocationInfo");
- if (lpTranslateCaps == NULL)
- return;
- lReturn = lineGetTranslateCaps(g_hLineApp, SAMPLE_TAPI_VERSION,
- lpTranslateCaps);
- if (HandleLineErr(lReturn))
- ;
- else
- {
- OutputDebugLineError(lReturn,
- "lineGetTranslateCaps unhandled error: ");
- LocalFree(lpTranslateCaps);
- return;
- }
- if ((lpTranslateCaps -> dwNeededSize) >
- (lpTranslateCaps -> dwTotalSize))
- {
- dwSizeofTranslateCaps = lpTranslateCaps ->dwNeededSize;
- lReturn = -1; // Lets loop again.
- }
- }
- while(lReturn != SUCCESS);
- // Find the location information in the TRANSLATECAPS
- lpLocationEntry = (LPLINELOCATIONENTRY)
- (((LPBYTE) lpTranslateCaps) + lpTranslateCaps->dwLocationListOffset);
- // If lpszCurrentLocation, then make that location 'current'
- if (lpszCurrentLocation)
- {
- // loop through all locations, looking for a location match
- for(dwCounter = 0;
- dwCounter < lpTranslateCaps -> dwNumLocations;
- dwCounter++)
- {
- if (strcmp((((LPSTR) lpTranslateCaps) +
- lpLocationEntry[dwCounter].dwLocationNameOffset),
- lpszCurrentLocation)
- == 0)
- {
- // Found it! Set the current location.
- lineSetCurrentLocation(g_hLineApp,
- lpLocationEntry[dwCounter].dwPermanentLocationID);
- // Set the return values.
- if (lpdwCountryID)
- *lpdwCountryID = lpLocationEntry[dwCounter].dwCountryID;
- if (lpszAreaCode)
- strcpy(lpszAreaCode, (((LPSTR) lpTranslateCaps) +
- lpLocationEntry[dwCounter].dwCityCodeOffset));
- // Store the preferred card ID for later use.
- dwPreferredCardID = lpLocationEntry[dwCounter].dwPreferredCardID;
- break;
- }
- }
- // Was a match for lpszCurrentLocation found?
- if (dwPreferredCardID == MAXDWORD)
- {
- OutputDebugString("lpszCurrentLocation not foundn");
- SendDlgItemMessage(hwndDlg, IDC_CALLINGCARD, WM_SETTEXT, 0,
- (LPARAM) (LPCSTR) "Invalid Location Selected");
- LocalFree(lpTranslateCaps);
- return;
- }
- }
- else // fill the combobox and use the TAPI 'current' location.
- {
- // First empty the combobox
- SendDlgItemMessage(hwndDlg, IDC_LOCATION, CB_RESETCONTENT, 0, 0);
- // enumerate all the locations
- for(dwCounter = 0;
- dwCounter < lpTranslateCaps -> dwNumLocations;
- dwCounter++)
- {
- // Put each one into the combobox
- lReturn = SendDlgItemMessage(hwndDlg, IDC_LOCATION, CB_ADDSTRING,
- 0, (LPARAM) (((LPBYTE) lpTranslateCaps) +
- lpLocationEntry[dwCounter].dwLocationNameOffset));
- // Is this location the 'current' location?
- if (lpLocationEntry[dwCounter].dwPermanentLocationID ==
- lpTranslateCaps->dwCurrentLocationID)
- {
- // Return the requested information
- if (lpdwCountryID)
- *lpdwCountryID = lpLocationEntry[dwCounter].dwCountryID;
- if (lpszAreaCode)
- strcpy(lpszAreaCode, (((LPSTR) lpTranslateCaps) +
- lpLocationEntry[dwCounter].dwCityCodeOffset));
- // Set this to be the active location.
- SendDlgItemMessage(hwndDlg, IDC_LOCATION, CB_SETCURSEL, lReturn, 0);
- dwPreferredCardID = lpLocationEntry[dwCounter].dwPreferredCardID;
- }
- }
- }
- // Now locate the prefered card and display it.
- lpLineCardEntry = (LPLINECARDENTRY)
- (((LPBYTE) lpTranslateCaps) + lpTranslateCaps->dwCardListOffset);
- for(dwCounter = 0;
- dwCounter < lpTranslateCaps -> dwNumCards;
- dwCounter++)
- {
- if (lpLineCardEntry[dwCounter].dwPermanentCardID == dwPreferredCardID)
- {
- SendDlgItemMessage(hwndDlg, IDC_CALLINGCARD, WM_SETTEXT, 0,
- (LPARAM) (((LPBYTE) lpTranslateCaps) +
- lpLineCardEntry[dwCounter].dwCardNameOffset));
- break;
- }
- }
- LocalFree(lpTranslateCaps);
- }
- //
- // FUNCTION: void UseDialingRules(HWND)
- //
- // PURPOSE: Enable/disable Dialing Rule controls
- //
- // PARAMETERS:
- // hwndDlg - handle to the current "Dial" dialog
- //
- // RETURN VALUE:
- // none
- //
- // COMMENTS:
- //
- // The sole purpose of this function is to enable or disable
- // the controls that apply to dialing rules if the
- // "Use Country Code and Area Code" checkbox is checked or unchecked,
- // as appropriate.
- //
- //
- void UseDialingRules(HWND hwndDlg)
- {
- HWND hControl;
- BOOL bEnableWindow;
- bEnableWindow = SendDlgItemMessage(hwndDlg,
- IDC_USEDIALINGRULES, BM_GETCHECK, 0, 0);
- hControl = GetDlgItem(hwndDlg, IDC_STATICCOUNTRYCODE);
- EnableWindow(hControl, bEnableWindow);
- hControl = GetDlgItem(hwndDlg, IDC_COUNTRYCODE);
- EnableWindow(hControl, bEnableWindow);
- hControl = GetDlgItem(hwndDlg, IDC_STATICAREACODE);
- EnableWindow(hControl, bEnableWindow);
- hControl = GetDlgItem(hwndDlg, IDC_AREACODE);
- EnableWindow(hControl, bEnableWindow);
- hControl = GetDlgItem(hwndDlg, IDC_STATICLOCATION);
- EnableWindow(hControl, bEnableWindow);
- hControl = GetDlgItem(hwndDlg, IDC_LOCATION);
- EnableWindow(hControl, bEnableWindow);
- hControl = GetDlgItem(hwndDlg, IDC_STATICCALLINGCARD);
- EnableWindow(hControl, bEnableWindow);
- hControl = GetDlgItem(hwndDlg, IDC_CALLINGCARD);
- EnableWindow(hControl, bEnableWindow);
- if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_CONFIGURELINE)))
- {
- hControl = GetDlgItem(hwndDlg, IDC_DIALINGPROPERTIES);
- EnableWindow(hControl, bEnableWindow);
- }
- }
- //
- // FUNCTION: void DisplayPhoneNumber(HWND)
- //
- // PURPOSE: Create, Translate and Display the Phone Number
- //
- // PARAMETERS:
- // hwndDlg - handle to the current "Dial" dialog
- //
- // RETURN VALUE:
- // none
- //
- // COMMENTS:
- //
- // This function uses the information stored in many other controls
- // to build the phone number, translate it, and display it. Also
- // makes sure the Dial button is enabled or disabled, based on if the
- // number can be dialed or not.
- //
- // There are actually three phone numbers generated during this
- // process: canonical, dialable and displayable. Normally, only the
- // displayable number is shown to the user; the other two numbers are
- // to be used by the program internally. However, for demonstration
- // purposes (and because it is cool for developers to see these numbers),
- // all three numbers are displayed.
- //
- void DisplayPhoneNumber(HWND hwndDlg)
- {
- char szPreTranslatedNumber[1024] = "";
- int nPreTranslatedSize = 0;
- char szTempBuffer[512];
- int i;
- DWORD dwDeviceID;
- LPLINETRANSLATEOUTPUT lpLineTranslateOutput = NULL;
- // Disable the 'dial' button if there isn't a number to dial
- if (0 == SendDlgItemMessage(hwndDlg, IDC_PHONENUMBER,
- WM_GETTEXTLENGTH, 0, 0))
- {
- SendDlgItemMessage(hwndDlg, IDC_CANONICALNUMBER, WM_SETTEXT, 0,
- (LPARAM) NULL);
- SendDlgItemMessage(hwndDlg, IDC_DIALABLENUMBER, WM_SETTEXT, 0,
- (LPARAM) NULL);
- SendDlgItemMessage(hwndDlg, IDC_DISPLAYABLENUMBER, WM_SETTEXT, 0,
- (LPARAM) (LPCTSTR) "No Phone Number");
- EnableWindow(GetDlgItem(hwndDlg, IDC_DIAL), FALSE);
- return;
- }
- // If we use the dialing rules, lets make canonical format.
- // Canonical format is explained in the TAPI documentation and the
- // string format needs to be followed very strictly.
- if (SendDlgItemMessage(hwndDlg, IDC_USEDIALINGRULES,
- BM_GETCHECK, 0, 0))
- {
- // First character *has* to be the plus sign.
- szPreTranslatedNumber[0] = '+';
- nPreTranslatedSize = 1;
- // The country code *has* to be next.
- // Country code was stored in the string with the country
- // name and needs to be extracted at this point.
- i = SendDlgItemMessage(hwndDlg, IDC_COUNTRYCODE,
- CB_GETCURSEL, 0, 0);
- SendDlgItemMessage(hwndDlg, IDC_COUNTRYCODE,
- CB_GETLBTEXT, (WPARAM) i, (LPARAM) (LPCTSTR) szTempBuffer);
- // Country code is at the end of the string, surounded by parens.
- // This makes it easy to identify the country code.
- i = strlen(szTempBuffer);
- while(szTempBuffer[--i] != '(');
- while(szTempBuffer[++i] != ')')
- szPreTranslatedNumber[nPreTranslatedSize++] = szTempBuffer[i];
- // Next is the area code.
- i = SendDlgItemMessage(hwndDlg, IDC_AREACODE, WM_GETTEXT,
- 510, (LPARAM) (LPCTSTR) szTempBuffer);
- // Note that the area code is optional. If it is included,
- // then it has to be preceeded by *exactly* one space and it
- // *has* to be surrounded by parens.
- if (i)
- nPreTranslatedSize +=
- wsprintf(&szPreTranslatedNumber[nPreTranslatedSize],
- " (%s)", szTempBuffer);
- // There has to be *exactly* one space before the rest of the number.
- szPreTranslatedNumber[nPreTranslatedSize++] = ' ';
- // At this point, the phone number is appended to the
- // canonical number. The next step is the same whether canonical
- // format is used or not; just the prepended area code and
- // country code are different.
- }
- SendDlgItemMessage(hwndDlg, IDC_PHONENUMBER, WM_GETTEXT,
- 510, (LPARAM) (LPCTSTR) szTempBuffer);
- strcat(&szPreTranslatedNumber[nPreTranslatedSize], szTempBuffer);
- dwDeviceID = SendDlgItemMessage(hwndDlg, IDC_TAPILINE,
- CB_GETCURSEL, 0, 0);
- // Translate the address!
- lpLineTranslateOutput = I_lineTranslateAddress(
- lpLineTranslateOutput, dwDeviceID, SAMPLE_TAPI_VERSION,
- szPreTranslatedNumber);
- // Unable to translate it?
- if (lpLineTranslateOutput == NULL)
- {
- SendDlgItemMessage(hwndDlg, IDC_CANONICALNUMBER, WM_SETTEXT, 0,
- (LPARAM) NULL);
- SendDlgItemMessage(hwndDlg, IDC_DIALABLENUMBER, WM_SETTEXT, 0,
- (LPARAM) NULL);
- SendDlgItemMessage(hwndDlg, IDC_DISPLAYABLENUMBER, WM_SETTEXT, 0,
- (LPARAM) (LPCTSTR) "Invalid Phone Number or Area Code");
- EnableWindow(GetDlgItem(hwndDlg, IDC_DIAL), FALSE);
- return;
- }
- // Is the selected device useable with TapiComm?
- if (g_dwDeviceID != MAXDWORD)
- EnableWindow(GetDlgItem(hwndDlg, IDC_DIAL), TRUE);
- // Fill the appropriate phone number controls.
- SendDlgItemMessage(hwndDlg, IDC_CANONICALNUMBER, WM_SETTEXT, 0,
- (LPARAM) (LPCTSTR) szPreTranslatedNumber);
- SendDlgItemMessage(hwndDlg, IDC_DIALABLENUMBER, WM_SETTEXT, 0,
- (LPARAM) ((LPSTR) lpLineTranslateOutput +
- lpLineTranslateOutput -> dwDialableStringOffset));
- SendDlgItemMessage(hwndDlg, IDC_DISPLAYABLENUMBER, WM_SETTEXT, 0,
- (LPARAM) ((LPSTR) lpLineTranslateOutput +
- lpLineTranslateOutput -> dwDisplayableStringOffset));
- LocalFree(lpLineTranslateOutput);
- }
- //
- // FUNCTION: void PreConfigureDevice(HWND, DWORD)
- //
- // PURPOSE:
- //
- // PARAMETERS:
- // hwndDlg - handle to the current "Dial" dialog
- // dwDeviceID - line device to be configured
- //
- // RETURN VALUE:
- // none
- //
- // COMMENTS:
- //
- // At one point, PreConfigureDevice used lineConfigDialog to
- // configure the device. This has the unfortunate effect of configuring
- // the device immediately, even if it is in use by another TAPI app.
- // This can be really bad if data communications are already in
- // progress (like with RAS).
- //
- // Now, PreConfigureDevice uses lineConfigDialogEdit to give the
- // user the configuration UI, but it doesn't actually do anything to
- // the line device. TapiComm stores the configuration information so
- // that it can be set later, just before making the call.
- //
- //
- void PreConfigureDevice(HWND hwndDlg, DWORD dwDeviceID)
- {
- long lReturn;
- LPVARSTRING lpVarString = NULL;
- DWORD dwSizeofVarString = sizeof(VARSTRING);
- // If there isn't already any device configuration information,
- // then we need to get some.
- if (g_lpDeviceConfig == NULL)
- {
- do
- {
- lpVarString = (LPVARSTRING) CheckAndReAllocBuffer(
- (LPVOID) lpVarString, dwSizeofVarString,
- "PreConfigureDevice - lineGetDevConfig: ");
- if (lpVarString == NULL)
- return;
- lReturn = lineGetDevConfig(dwDeviceID, lpVarString,
- "comm/datamodem");
- if (HandleLineErr(lReturn))
- ;
- else
- {
- OutputDebugLineError(lReturn,
- "lineGetDevCaps unhandled error: ");
- LocalFree(lpVarString);
- return;
- }
- if ((lpVarString -> dwNeededSize) > (lpVarString -> dwTotalSize))
- {
- dwSizeofVarString = lpVarString -> dwNeededSize;
- lReturn = -1; // Lets loop again.
- }
- }
- while (lReturn != SUCCESS);
- g_dwSizeDeviceConfig = lpVarString -> dwStringSize;
- // The extra byte allocated is in case dwStringSize is 0.
- g_lpDeviceConfig = CheckAndReAllocBuffer(
- g_lpDeviceConfig, g_dwSizeDeviceConfig+1,
- "PreConfigureDevice - Allocate device config: ");
- if (!g_lpDeviceConfig)
- {
- LocalFree(lpVarString);
- return;
- }
- memcpy(g_lpDeviceConfig,
- ((LPBYTE) lpVarString + lpVarString -> dwStringOffset),
- g_dwSizeDeviceConfig);
- }
- // Next make the lineConfigDialogEdit call.
- // Note that we determine the initial size of the VARSTRING
- // structure based on the known size of the existing configuration
- // information. I make the assumption that this configuration
- // information is very unlikely to grow by more than 5K or by
- // more than 5 times. This is a *very* conservative number.
- // We do *not* want lineConfigDialogEdit to fail just because there
- // wasn't enough room to stored the data. This would require the user
- // to go through configuration again and that would be annoying.
- dwSizeofVarString = 5 * g_dwSizeDeviceConfig + 5000;
- do
- {
- lpVarString = (LPVARSTRING) CheckAndReAllocBuffer(
- (LPVOID) lpVarString, dwSizeofVarString,
- "PreConfigureDevice - lineConfigDialogEdit: ");
- if (lpVarString == NULL)
- return;
- lReturn = lineConfigDialogEdit(dwDeviceID, hwndDlg, "comm/datamodem",
- g_lpDeviceConfig, g_dwSizeDeviceConfig, lpVarString);
- if (HandleLineErr(lReturn))
- ;
- else
- {
- OutputDebugLineError(lReturn,
- "lineConfigDialogEdit unhandled error: ");
- LocalFree(lpVarString);
- return;
- }
- if ((lpVarString -> dwNeededSize) > (lpVarString -> dwTotalSize))
- {
- // We had been conservative about making sure the structure was
- // big enough. Unfortunately, not conservative enough. Hopefully,
- // this will not happen a second time because we are *DOUBLING*
- // the NeededSize.
- MessageBox(hwndDlg,
- "Internal Error: Unable to set line configuration.n"
- "Please try again.",
- "Oops", MB_OK);
- dwSizeofVarString = (lpVarString -> dwNeededSize) * 2;
- lReturn = -1; // Lets loop again.
- }
- }
- while (lReturn != SUCCESS);
- // Store the configuration information into a global structure
- // so it can be set at a later time.
- g_dwSizeDeviceConfig = lpVarString -> dwStringSize;
- g_lpDeviceConfig = CheckAndReAllocBuffer(
- g_lpDeviceConfig, g_dwSizeDeviceConfig+1,
- "PreConfigureDevice - Reallocate device config: ");
- if (!g_lpDeviceConfig)
- {
- LocalFree(lpVarString);
- return;
- }
- memcpy(g_lpDeviceConfig,
- ((LPBYTE) lpVarString + lpVarString -> dwStringOffset),
- g_dwSizeDeviceConfig);
- LocalFree(lpVarString);
- }
- //
- // FUNCTION: BOOL GetAddressToDial
- //
- // PURPOSE: Get an address to dial from the user.
- //
- // PARAMETERS:
- // none
- //
- // RETURN VALUE:
- // TRUE if a valid device and phone number have been entered by
- // the user. FALSE if the user canceled the dialing process.
- //
- // COMMENTS:
- //
- // All this function does is launch the "Dial" dialog.
- //
- //
- BOOL GetAddressToDial()
- {
- BOOL bRet;
- UpdateStatusBar("Getting Number to Dial",1,0);
- bRet = DialogBoxParam(hInst, "DialDialog", g_hDlgParentWindow,
- DialDialogProc, 0);
- g_hDialog = NULL;
- g_hDlgParentWindow = g_hWndMainWindow;
- if (bRet == FALSE)
- UpdateStatusBar("Dial aborted",1,0);
- return bRet;
- }
- //
- // FUNCTION: DialDialogProc(HWND, UINT, WPARAM, LPARAM)
- //
- // PURPOSE: Dialog callback procedure for the dialing dialog
- //
- // PARAMETERS:
- // hwndDlg - Dialog calling the callback.
- // uMsg - Dialog message.
- // wParam - uMsg specific.
- // lParam - uMsg specific.
- //
- // RETURN VALUE:
- // returns 0 - command handled.
- // returns non-0 - command unhandled
- //
- // COMMENTS:
- //
- // This is the dialog to get the phone number and line device
- // from the user. All the relavent information is stored in global
- // variables to be used later if the dialog returns successfully.
- //
- //
- BOOL CALLBACK DialDialogProc(
- HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- // Static variables to store the information from last time the
- // "Dial" dialog was displayed. That way the phone number can be
- // typed once but used several times.
- static char szCountryName[512] = "";
- static char szAreaCode[256] = "Not Valid";
- static char szPhoneNumber[512] = "Not Valid";
- static DWORD dwUsedDeviceID = MAXDWORD;
- static BOOL bUsedCountryAndArea = FALSE;
- static BOOL bHistoryValid = FALSE;
- switch(uMsg)
- {
- case WM_INITDIALOG:
- {
- DWORD dwCountryID = 0;
- // Store the Dialog Window so it can be dismissed if necessary
- g_hDialog = hwndDlg;
- // This dialog should be parent to all dialogs.
- g_hDlgParentWindow = hwndDlg;
- // Initialize the Dialog Box. Lots to do here.
- FillTAPILine(hwndDlg);
- if (g_lpDeviceConfig)
- {
- LocalFree(g_lpDeviceConfig);
- g_lpDeviceConfig = NULL;
- }
- // If there is a valid history, use it to initialize the controls.
- if (bHistoryValid)
- {
- FillLocationInfo(hwndDlg, NULL, NULL, NULL);
- FillCountryCodeList(hwndDlg, 0);
- SendDlgItemMessage(hwndDlg, IDC_COUNTRYCODE, CB_SELECTSTRING,
- (WPARAM) -1, (LPARAM) (LPCTSTR) szCountryName);
- SendDlgItemMessage(hwndDlg, IDC_PHONENUMBER, WM_SETTEXT, 0,
- (LPARAM) (LPCTSTR) szPhoneNumber);
- SendDlgItemMessage(hwndDlg, IDC_USEDIALINGRULES,
- BM_SETCHECK, (WPARAM) bUsedCountryAndArea, 0);
- SendDlgItemMessage(hwndDlg, IDC_TAPILINE, CB_SETCURSEL,
- g_dwDeviceID, 0);
- }
- else
- {
- FillLocationInfo(hwndDlg, NULL, &dwCountryID, szAreaCode);
- FillCountryCodeList(hwndDlg, dwCountryID);
- SendDlgItemMessage(hwndDlg, IDC_USEDIALINGRULES,
- BM_SETCHECK, 1, 0);
- }
- SendDlgItemMessage(hwndDlg, IDC_AREACODE, WM_SETTEXT,
- 0, (LPARAM) (LPCTSTR) szAreaCode);
- UseDialingRules(hwndDlg);
- DisplayPhoneNumber(hwndDlg);
- VerifyAndWarnUsableLine(hwndDlg);
- return TRUE;
- }
- case WM_COMMAND:
- {
- switch(LOWORD(wParam))
- {
- case IDC_TAPILINE:
- if (HIWORD(wParam) == CBN_SELENDOK)
- {
- if (g_lpDeviceConfig)
- {
- LocalFree(g_lpDeviceConfig);
- g_lpDeviceConfig = NULL;
- }
- DisplayPhoneNumber(hwndDlg);
- VerifyAndWarnUsableLine(hwndDlg);
- }
- return TRUE;
- case IDC_CONFIGURELINE:
- {
- DWORD dwDeviceID;
- dwDeviceID = SendDlgItemMessage(hwndDlg, IDC_TAPILINE,
- CB_GETCURSEL, 0, 0);
- PreConfigureDevice(hwndDlg, dwDeviceID);
- DisplayPhoneNumber(hwndDlg);
- return TRUE;
- }
- case IDC_COUNTRYCODE:
- if (HIWORD(wParam) == CBN_SELENDOK)
- DisplayPhoneNumber(hwndDlg);
- return TRUE;
- case IDC_AREACODE:
- case IDC_PHONENUMBER:
- if (HIWORD(wParam) == EN_CHANGE)
- DisplayPhoneNumber(hwndDlg);
- return TRUE;
- case IDC_USEDIALINGRULES:
- if (HIWORD(wParam) == BN_CLICKED)
- {
- UseDialingRules(hwndDlg);
- DisplayPhoneNumber(hwndDlg);
- }
- return TRUE;
- case IDC_LOCATION:
- if (HIWORD(wParam) == CBN_CLOSEUP)
- {
- char szCurrentLocation[1024];
- int nCurrentSelection;
- nCurrentSelection = SendDlgItemMessage(hwndDlg,
- IDC_LOCATION, CB_GETCURSEL, 0, 0);
- SendDlgItemMessage(hwndDlg, IDC_LOCATION,
- CB_GETLBTEXT, nCurrentSelection,
- (LPARAM) (LPCTSTR) szCurrentLocation);
- // If the user selected a 'location', make it current.
- FillLocationInfo(hwndDlg, szCurrentLocation, NULL, NULL);
- DisplayPhoneNumber(hwndDlg);
- }
- return TRUE;
- case IDC_DIALINGPROPERTIES:
- {
- char szAddress[1024];
- DWORD dwDeviceID;
- long lReturn;
- dwDeviceID = SendDlgItemMessage(hwndDlg, IDC_TAPILINE,
- CB_GETCURSEL, 0, 0);
- SendDlgItemMessage(hwndDlg, IDC_CANONICALNUMBER,
- WM_GETTEXT, 1023, (LPARAM) (LPCTSTR) szAddress);
- lReturn = lineTranslateDialog(g_hLineApp, dwDeviceID,
- SAMPLE_TAPI_VERSION, hwndDlg, szAddress);
- if (lReturn != SUCCESS)
- OutputDebugLineError(lReturn,"lineTranslateDialog: ");
- // The user could have changed the default location, or
- // added or removed a location while in the 'Dialing
- // Properties' dialog. Refill the Location Info.
- FillLocationInfo(hwndDlg, NULL, NULL, NULL);
- DisplayPhoneNumber(hwndDlg);
- return TRUE;
- }
- case IDCANCEL:
- EndDialog(hwndDlg, FALSE);
- return TRUE;
- case IDC_DIAL:
- {
- // The Dial button has to be enabled and the line has
- // to be currently usable to continue.
- if (!(IsWindowEnabled((HWND)lParam) &&
- VerifyAndWarnUsableLine(hwndDlg)))
- return TRUE;
- DisplayPhoneNumber(hwndDlg);
- // Get the displayable and dialable numbers and store
- // them in global variables to be used while dialing.
- SendDlgItemMessage(hwndDlg, IDC_DISPLAYABLENUMBER,
- WM_GETTEXT, 1023, (LPARAM) (LPCTSTR) g_szDisplayableAddress);
- SendDlgItemMessage(hwndDlg, IDC_DIALABLENUMBER,
- WM_GETTEXT, 1023, (LPARAM) (LPCTSTR) g_szDialableAddress);
- // Store all the relavent information in static
- // variables so they will be available the next time a
- // number is dialed.
- SendDlgItemMessage(hwndDlg, IDC_COUNTRYCODE,
- WM_GETTEXT, 511, (LPARAM) (LPCTSTR) szCountryName);
- SendDlgItemMessage(hwndDlg, IDC_AREACODE,
- WM_GETTEXT, 255, (LPARAM) (LPCTSTR) szAreaCode);
- SendDlgItemMessage(hwndDlg, IDC_PHONENUMBER,
- WM_GETTEXT, 511, (LPARAM) (LPCTSTR) szPhoneNumber);
- bUsedCountryAndArea = (BOOL) SendDlgItemMessage(hwndDlg,
- IDC_USEDIALINGRULES, BM_GETCHECK, 0, 0);
- bHistoryValid = TRUE;
- EndDialog(hwndDlg, TRUE);
- return TRUE;
- }
- // This message is actually posted to the dialog from the
- // lineCallbackFunc when it receives a
- // LINEDEVSTATE_TRANSLATECHANGE message. Notify the user and
- // retranslate the number. Also refill the Location Info
- // since this could have been generated by a location change.
- case IDC_CONFIGURATIONCHANGED:
- {
- FillLocationInfo(hwndDlg, NULL, NULL, NULL);
- DisplayPhoneNumber(hwndDlg);
- MessageBox(hwndDlg,
- "Location Configuration has been changed.",
- "Warning",MB_OK);
- return TRUE;
- }
- // If we get a LINE_CREATE message, all that needs to be done
- // is to reset this controls contents. The selected line
- // won't change and no lines will be removed.
- case IDC_LINECREATE:
- {
- FillTAPILine(hwndDlg);
- return TRUE;
- }
- default:
- break;
- }
- break;
- }
- // This dialog has the DS_CONTEXTMENU flag so that the right mouse
- // button will send this message. Bring up the appropriate help page.
- case WM_CONTEXTMENU:
- {
- if (hwndDlg != (HWND) wParam)
- WinHelp ((HWND)wParam,
- "TAPICOMM.HLP",
- HELP_CONTEXTMENU,
- (DWORD)(LPVOID) g_adwSampleMenuHelpIDs);
- break;
- }
- // Bring up the appropriate help page.
- case WM_HELP:
- {
- LPHELPINFO lphi;
- lphi = (LPHELPINFO)lParam;
- if ((lphi->iContextType == HELPINFO_WINDOW) &&
- (hwndDlg != lphi->hItemHandle) &&
- (lphi->iCtrlId < IDC_NOHELPCONTROLS))
- {
- WinHelp (lphi->hItemHandle,
- "TAPICOMM.HLP",
- HELP_WM_HELP,
- (DWORD)(LPVOID) g_adwSampleMenuHelpIDs);
- }
- return TRUE;
- }
- default:
- break;
- }
- return FALSE;
- }