Serial Port Communication using Bluetooth not Receiving Response, VC++, MFC - mfc

I am developing a ELM327 Simulator device(http://en.wikipedia.org/wiki/ELM327) using VC++ in MFC..It implements Serial port communication with my PC and tab..My Pc contains BLuetooth plugged into it and the device (tab) is being paired with my PC..My program should send the required result for the received response..
Eg:
For Speed, Command : 010D should respond with output 41 0D 12
My problrm is that it is not receiving response from PC after sending command..What could probably the reason be..
Thanks to All
My code For ReceiveData is Like This.
LRESULT CELM327SimDlg::OnReceiveData(WPARAM wParam, LPARAM lParam)
{
int iLen = (int)wParam; // iLen has value 5
LPBYTE lpDataBuffer = (LPBYTE)lParam;
//lpDataBuffer has value AT Z
// Parse and handle the received here.
WORD wCmd = m_ELM327Cmd.ParseAndGetCmd(lpDataBuffer, iLen); //Goes to ParseAndGetCmd function
if( ELM327_CMD_SUP_CMD == wCmd ) //If condition fails program control goes to else part
{
for( int i = 0; i < 3; i++ )
{
m_objSerialPort.SendData(m_ELM327Cmd.GetSupBuf(i), m_ELM327Cmd.GetSupBufLen());
}
}
else
{
DWORD dwData = 0;
switch(wCmd) // Not getting to switch block
{
case ELM327_CMD_RPM:
dwData = m_ctrlRPMSlider.GetPos();
break;
case ELM327_CMD_SPEED:
dwData = m_ctrlSpeedSlider.GetPos();
break;
case ELM327_CMD_MAF:
dwData = m_ctrlMAFSlider.GetPos();
break;
case ELM327_CMD_FUELLVL:
dwData = m_ctrlFuelSlider.GetPos();break;
default:break;
}
if(m_ELM327Cmd.SetResponse(wCmd, dwData)) //Program calling SetResponse function.
{
m_objSerialPort.SendData(m_ELM327Cmd.GetResponseBuf(), m_ELM327Cmd.GetResponseLen());
}
}
if( NULL != lpDataBuffer )
{
delete [] lpDataBuffer;
lpDataBuffer = NULL;
}
return 0;
}
SendData Function is as follows
// Send data to comport
void CSerialPort::SendData(LPBYTE lpBuffer, DWORD dwBytes)
{
if(m_bConnected)
{
if( NULL == lpBuffer || dwBytes == 0 )
{
return;
}
LPBYTE lpDataBuffer = new BYTE[dwBytes];
if( NULL == lpDataBuffer )
{
return;
}
CopyMemory(lpDataBuffer, lpBuffer, dwBytes );
::PostMessage( m_hWnd, UWM_SEND_DATA, (WPARAM)dwBytes, (LPARAM)lpDataBuffer );
}
return;
}

Related

DirectSound captures gigabytes of frames instead of megabytes

I am using DirectSound to capture the sound of my desktop, using the tutorial from MSDN https://msdn.microsoft.com/en-us/library/windows/desktop/ee416968(v=vs.85).aspx
The problem is that when I start to capture, my WAV file gets to hundreds of MB and even GB, in a few seconds.When I play the WAV file, 5 seconds of audio capture become 30 minutes, and the same frame of sound is duplicated like 1000 times.I have noticed that WAIT_OBJECT_0 + 1 and 2 are never fired.Thanks in advance.
bool captureSound = false;
wav_header wavFile; // the wav file
UINT totalData = 0;
LPDIRECTSOUNDCAPTURE8 capturer = NULL;
GUID guid = DSDEVID_DefaultCapture;
HRESULT err;
DSCBUFFERDESC dscbd;
LPDIRECTSOUNDCAPTUREBUFFER8 pDSCB8;
DWORD g_dwNextCaptureOffset = 0;
DWORD g_dwCaptureBufferSize = 0;
DWORD g_dwNotifySize = 0;
#define cEvents 3
WAVEFORMATEX wfx;
HANDLE rghEvent[cEvents] = {0,0,0};
DSBPOSITIONNOTIFY rgdsbpn[cEvents];
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
BOOL bDone;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_WIN32PROJECT2, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WIN32PROJECT2));
bDone = FALSE;
// Main message loop:
while( !bDone ) {
dwResult = MsgWaitForMultipleObjects( 3, rghEvent,
FALSE, INFINITE, QS_ALLEVENTS );
switch( dwResult ) {
case WAIT_OBJECT_0 + 0:
if(FAILED(RecordCapturedData())) MessageBox(NULL,TEXT("Error!"), TEXT("Error"), MB_OK);
break;
case WAIT_OBJECT_0 + 1:
if(FAILED(RecordCapturedData())) MessageBox(NULL,TEXT("Error!"), TEXT("Error"), MB_OK);
break;
case WAIT_OBJECT_0 + 2:
if(FAILED(RecordCapturedData())) MessageBox(NULL,TEXT("Error!"), TEXT("Error"), MB_OK);
break;
case WAIT_OBJECT_0 + 3:
//MessageBox(NULL,TEXT("wait3"), TEXT("Error"), MB_OK);
// Windows messages are available
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if( msg.message == WM_QUIT )
bDone = TRUE;
}
break;
}
}
//CloseHandle(rghEvent);
return (int) msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_CAPTURESOUND:
captureSound = true;
if (FAILED(createWav(&wavFile)))
{
closeWav(wavFile.pFile);
MessageBox(NULL,TEXT("Error creating the sound file!"), TEXT("Error"), MB_OK);
}
// add the WAV header
for(int i = 0; i < 4; i++) {
fputc(wavFile.riff_header[i], wavFile.pFile);
}
fwrite((char*)&wavFile.wav_size,sizeof(int),1,wavFile.pFile);
for(int i = 0; i < 4; i++) {
fputc(wavFile.wave_header[i], wavFile.pFile);
}
for(int i = 0; i < 4; i++) {
fputc(wavFile.fmt_header[i], wavFile.pFile);
}
fwrite((const char*)&wavFile.fmt_chunk_size,4,1,wavFile.pFile);
fwrite((const char*)&wavFile.audio_format,2,1,wavFile.pFile);
fwrite((const char*)&wavFile.num_channels,2,1,wavFile.pFile);
fwrite((const char*)&wavFile.sample_rate,4,1,wavFile.pFile);
fwrite((const char*)&wavFile.byte_rate,4,1,wavFile.pFile);
fwrite((const char*)&wavFile.sample_alignment,2,1,wavFile.pFile);
fwrite((const char*)&wavFile.bit_depth,2,1,wavFile.pFile);
for(int i = 0; i < 4; i++) {
fputc(wavFile.data_header[i], wavFile.pFile);
}
fwrite((const char*)&wavFile.data_bytes,4,1,wavFile.pFile);
/* Use DirectSoundCaptureCreate8() to create and initialize an object and get the pointer (pDSC8) to IDirectSoundCapture8 */
if(FAILED(DirectSoundCaptureCreate8(&guid, &capturer, NULL))) {
ErrorExit(TEXT("DirectSoundCaptureCreate8"));
}
/* Use the method CreateCaptureBuffer() of IDirectSoundCapture8(pDSC8->CreateSoundBuffer()) to create
and initialize an object and get the pointer (pDSCB) to IDirectSoundCaptureBuffer. */
if(FAILED(CreateCaptureBuffer(capturer,&pDSCB8))) {
ErrorExit(TEXT("CreateCaptureBuffer"));
}
/* Use the method QueryInterface of IDirectSoundCaptureBuffer8(pDSCB8->QueryInterface()) to get a pointer(lpDsNotify) to the interface IDirectSoundNotify8. */
if(FAILED(SetCaptureNotifications(pDSCB8))) {
ErrorExit(TEXT("SetCaptureNotifications"));
}
/* Start capturing */
if(FAILED(pDSCB8->Start( DSCBSTART_LOOPING ) ) )
ErrorExit(TEXT("Start"));
else MessageBox(NULL,TEXT("Started capturing!"), TEXT("Good"), MB_OK);
break;
case IDM_OPRESTE:
captureSound = false;
// Stop the buffer, and read any data that was not
// caught by a notification
if( FAILED(pDSCB8->Stop() ) )
ErrorExit(TEXT("Stop"));
if(FAILED(RecordCapturedData())) MessageBox(NULL,TEXT("ERROR "), TEXT("Error"), MB_OK);
/* Update the fields in the WAV header and close the file */
fseek (wavFile.pFile, 4 , SEEK_SET );
wavFile.wav_size += totalData;
fwrite((char*)&wavFile.wav_size,sizeof(int),1,wavFile.pFile);
wavFile.data_bytes += totalData;
fseek (wavFile.pFile, 40 , SEEK_SET );
fwrite((char*)&wavFile.data_bytes,sizeof(int),1,wavFile.pFile);
closeWav(wavFile.pFile);
break;
case IDM_EXIT:
DestroyWindow(hWnd); // POSTS THE MESSAGE WM_DESTROY TO DESTROY THE CREATED WINDOW.
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_CREATE:
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
HRESULT CreateCaptureBuffer(LPDIRECTSOUNDCAPTURE8 pDSC,
LPDIRECTSOUNDCAPTUREBUFFER8* ppDSCB8)
{
HRESULT hr;
DSCBUFFERDESC dscbd;
LPDIRECTSOUNDCAPTUREBUFFER pDSCB;
// Set up WAVEFORMATEX for 44.1 kHz 16-bit stereo.
WAVEFORMATEX wfx =
{WAVE_FORMAT_PCM, wavFile.num_channels, wavFile.sample_rate, wavFile.byte_rate, wavFile.sample_alignment, wavFile.bit_depth, 0};
// wFormatTag, nChannels, nSamplesPerSec, mAvgBytesPerSec,
// nBlockAlign, wBitsPerSample, cbSize
if ((NULL == pDSC) || (NULL == ppDSCB8)) return E_INVALIDARG;
dscbd.dwSize = sizeof(DSCBUFFERDESC);
dscbd.dwFlags = 0;
dscbd.dwBufferBytes = wfx.nAvgBytesPerSec;
dscbd.dwReserved = 0;
dscbd.lpwfxFormat = &wfx;
dscbd.dwFXCount = 0;
dscbd.lpDSCFXDesc = NULL;
g_dwNotifySize = MAX( 1024, wavFile.byte_rate / 8 );
g_dwNotifySize -= g_dwNotifySize % wavFile.sample_alignment;
g_dwCaptureBufferSize = g_dwNotifySize * 3;
if (SUCCEEDED(hr = pDSC->CreateCaptureBuffer(&dscbd, &pDSCB, NULL)))
{
/* Use the method QueryInterface of IDirectSoundCaptureBuffer(pDSCB->QueryInterface()) to get a
pointer(pDSCB8) to the interface IDirectSoundCaptureBuffer8 */
hr = pDSCB->QueryInterface(IID_IDirectSoundCaptureBuffer8, (LPVOID*)ppDSCB8);
pDSCB->Release();
}
return hr;
}
HRESULT SetCaptureNotifications(LPDIRECTSOUNDCAPTUREBUFFER8 pDSCB)
{
LPDIRECTSOUNDNOTIFY8 pDSNotify;
HRESULT hr;
if (NULL == pDSCB) return E_INVALIDARG;
if (FAILED(hr = pDSCB->QueryInterface(IID_IDirectSoundNotify, (LPVOID*)&pDSNotify)))
{
return hr;
}
if (FAILED(hr = pDSCB->GetFormat(&wfx, sizeof(WAVEFORMATEX), NULL)))
{
return hr;
}
// Create events.
for (int i = 0; i < cEvents; ++i)
{
rghEvent[i] = CreateEvent(NULL, TRUE, FALSE, NULL);
if (NULL == rghEvent[i])
{
hr = GetLastError();
return hr;
}
}
// Describe notifications.
rgdsbpn[0].dwOffset = (wfx.nAvgBytesPerSec/2) -1;
rgdsbpn[0].hEventNotify = rghEvent[0];
rgdsbpn[1].dwOffset = wfx.nAvgBytesPerSec - 1;
rgdsbpn[1].hEventNotify = rghEvent[1];
rgdsbpn[2].dwOffset = DSBPN_OFFSETSTOP;
rgdsbpn[2].hEventNotify = rghEvent[2];
/* Use the SetNotificationPositions() of IDirectSoundNotify8(lpDsNotify->SetNotificationPositions())
to set the notification buffer positions */
hr = pDSNotify->SetNotificationPositions(cEvents, rgdsbpn);
pDSNotify->Release();
return hr;
}
HRESULT RecordCapturedData()
{
HRESULT hr;
VOID* pbCaptureData = NULL;
DWORD dwCaptureLength;
VOID* pbCaptureData2 = NULL;
DWORD dwCaptureLength2;
VOID* pbPlayData = NULL;
UINT dwDataWrote;
DWORD dwReadPos;
LONG lLockSize;
if (NULL == pDSCB8)
MessageBox(NULL,TEXT("Empty buffer!"), TEXT("Error"), MB_OK);
if (NULL == wavFile.pFile)
MessageBox(NULL,TEXT("Empty .wav file!"), TEXT("Error"), MB_OK);
if (FAILED (hr = pDSCB8->GetCurrentPosition(
NULL, &dwReadPos)))
MessageBox(NULL,TEXT("Failed to get current position!"), TEXT("Error"), MB_OK);
// Lock everything between the private cursor
// and the read cursor, allowing for wraparound.
lLockSize = dwReadPos - g_dwNextCaptureOffset;
if( lLockSize < 0 ) lLockSize += g_dwCaptureBufferSize;
// Block align lock size so that we are always write on a boundary
//lLockSize -= (lLockSize % g_dwNotifySize);
if( lLockSize == 0 ) return S_FALSE;
if (FAILED(hr = pDSCB8->Lock(
g_dwNextCaptureOffset, lLockSize,
&pbCaptureData, &dwCaptureLength,
&pbCaptureData2, &dwCaptureLength2, 0L)))
MessageBox(NULL,TEXT("Lock failed!"), TEXT("Error"), MB_OK);
// Write the data. This is done in two steps
// to account for wraparound.
if (FAILED( addData(&wavFile, (BYTE*)pbCaptureData, dwCaptureLength, &dwDataWrote)))
MessageBox(NULL,TEXT("Error writting to the file!"), TEXT("Error"), MB_OK);
if (pbCaptureData2 != NULL)
{
if (FAILED( addData(&wavFile, (BYTE*)pbCaptureData2, dwCaptureLength2, &dwDataWrote)))
MessageBox(NULL,TEXT("Error writting to the file 2!"), TEXT("Error"), MB_OK);
}
// Unlock the capture buffer.
pDSCB8->Unlock( pbCaptureData, dwCaptureLength,
pbCaptureData2, dwCaptureLength2 );
// Move the capture offset forward.
g_dwNextCaptureOffset += dwCaptureLength;
g_dwNextCaptureOffset %= g_dwCaptureBufferSize;
g_dwNextCaptureOffset += dwCaptureLength2;
g_dwNextCaptureOffset %= g_dwCaptureBufferSize;
totalData += (dwCaptureLength + dwCaptureLength2);
return S_OK;
}
Wav writer utility
#include "stdafx.h"
#include "Wav.h"
HRESULT createWav(wav_header* pWav) {
pWav->pFile = fopen("sound.wav","w");
if(pWav->pFile == NULL) {
return 0;
}
strcpy(pWav->riff_header, "RIFF");
strcpy(pWav->wave_header, "WAVE");
strcpy(pWav->fmt_header, "fmt ");
pWav->fmt_chunk_size = 16;
pWav->audio_format = 1;
pWav->num_channels = 2;
pWav->sample_rate = 44100; // 44.1 KHz - CD-quality audio
pWav->bit_depth = 16; // Bits per Sample – The number of bits available for one sample.
pWav->sample_alignment = pWav->num_channels * (pWav->bit_depth)/8; // This is the number of bytes in a frame
pWav->byte_rate = pWav->sample_rate * pWav->sample_alignment; // number of bytes per second captured
strcpy(pWav->data_header, "data");
pWav->data_bytes = 0; // n * frames , n = 0 empty data default, to be updated each time new data is added
pWav->wav_size = 36 + pWav->data_bytes; // to be updated each time new data is added
return S_OK;
}
HRESULT closeWav(FILE * pFile) {
fclose(pFile);
return S_OK;
}
HRESULT addData(wav_header* pWav, VOID* data,UINT dataLength, UINT* dataWrote) {
// set the positon back at the end of the file
fseek (pWav->pFile, 0 , SEEK_END );
*dataWrote = fwrite((const char*)data,sizeof(byte),(size_t)dataLength, pWav->pFile);
return S_OK;
}

EnumDesktopWindows (C++) takes about 30 mins to find the desired open Window on Windows 10

This problem occurs only on Windows 10. Works fine on other versions such as Windows 7.
On user action, I have following code to find out another open application window as:
void zcTarget::LocateSecondAppWindow( void )
{
ghwndAppWindow = NULL;
CString csQuickenTitleSearch = "MySecondApp";
::EnumDesktopWindows( hDesktop, MyCallback, (LPARAM)(LPCTSTR)csTitleSearch );
}
With callback functions as:
BOOL CALLBACK MyCallback( HWND hwnd, LPARAM lParam)
{
if ( ::GetWindowTextLength( hwnd ) == 0 )
{
return TRUE;
}
CString strText;
GetWindowText( hwnd, strText.GetBuffer( 256 ), 256 );
strText.ReleaseBuffer();
if ( strText.Find( (LPCTSTR)lParam ) == 0 )
{
// We found the desired app HWND, so save it off, and return FALSE to
// tell EnumDesktopWindows to stopping iterating desktop HWNDs.
ghwndAppWindow = hwnd;
return FALSE;
}
return TRUE;
} // This is the line after which call is not returned for about 30 mins
This callback function mentioned above gets called for about 7 times, each time returning True. At this stage it finds own app window through which EnumDesktopWindows was invoked.
It returns True as expected, but then nothing happens for about 30 minutes. No debug points hit. The original running application is unresponsive at this point.
How to resolve this problem?
Found another path. Instead of going by Window name, looking for Process helps. Get process using process name, extract process id and get window handle.
void zcTarget::LocateSecondAppWindow( void )
{
PROCESSENTRY32 entry;
entry.dwSize = sizeof(PROCESSENTRY32);
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if (Process32First(snapshot, &entry) == TRUE)
{
while (Process32Next(snapshot, &entry) == TRUE)
{
if (_stricmp(entry.szExeFile, "myApp.exe") == 0)
{
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);
EnumData ed = { GetProcessId( hProcess ) };
if ( !EnumWindows( EnumProc, (LPARAM)&ed ) &&
( GetLastError() == ERROR_SUCCESS ) ) {
ghwndQuickenWindow = ed.hWnd;
}
CloseHandle(hProcess);
break;
}
}
}
CloseHandle(snapshot);
}
BOOL CALLBACK EnumProc( HWND hWnd, LPARAM lParam ) {
// Retrieve storage location for communication data
zcmTaxLinkProTarget::EnumData& ed = *(zcmTaxLinkProTarget::EnumData*)lParam;
DWORD dwProcessId = 0x0;
// Query process ID for hWnd
GetWindowThreadProcessId( hWnd, &dwProcessId );
// Apply filter - if you want to implement additional restrictions,
// this is the place to do so.
if ( ed.dwProcessId == dwProcessId ) {
// Found a window matching the process ID
ed.hWnd = hWnd;
// Report success
SetLastError( ERROR_SUCCESS );
// Stop enumeration
return FALSE;
}
// Continue enumeration
return TRUE;
}

Cannot receive SNMP Trap with WinSNMP APIs

I'm writing a simple and small SNMP manager program with WinSNMP.
But it cannot receive trap events...
Can anyone help me?
Here's sample code:
#include <stdio.h>
#include <Winsnmp.h>
SNMPAPI_STATUS CALLBACK MySnmpCallback(
HSNMP_SESSION hSession,
HWND hWnd,
UINT wMsg,
WPARAM wParam,
LPARAM lParam,
LPVOID lpClientData
)
{
printf("MySnmpCallback!\n");
return SNMPAPI_SUCCESS;
}
void SnmpTest()
{
smiUINT32 nMajorVersion;
smiUINT32 nMinorVersion;
smiUINT32 nLevel;
smiUINT32 nTranslateMode;
smiUINT32 nRetransmitMode;
SNMPAPI_STATUS statusStartup = SnmpStartupEx(
&nMajorVersion,
&nMinorVersion,
&nLevel,
&nTranslateMode,
&nRetransmitMode
);
if (SNMPAPI_SUCCESS == statusStartup)
{
printf(" MajorVersion = %u\n", nMajorVersion);
printf(" MinorVersion = %u\n", nMinorVersion);
printf(" Level = %u\n", nLevel);
printf("RetransmitMode = %u\n", nRetransmitMode);
SnmpSetTranslateMode(SNMPAPI_UNTRANSLATED_V2);
SnmpGetTranslateMode(&nTranslateMode);
printf(" TranslateMode = %u\n", nTranslateMode);
}
else
{
printf("SnmpStartup Failed. (%u)\n", SnmpGetLastError(NULL));
}
if (SNMPAPI_SUCCESS == statusStartup)
{
HSNMP_SESSION hSession = SnmpCreateSession(NULL, NULL, (SNMPAPI_CALLBACK)&MySnmpCallback, NULL);
if (SNMPAPI_FAILURE != hSession)
{
HSNMP_ENTITY localEntity = SnmpStrToEntity(hSession, "0.0.0.0");
SNMPAPI_STATUS regStatus = SnmpRegister(hSession, localEntity, NULL, NULL, NULL, SNMPAPI_ON);
if (SNMPAPI_SUCCESS == regStatus)
{
while (TRUE)
{
Sleep(100);
if (GetKeyState('A') && 0x8000)
break;
}
SnmpClose(hSession);
}
else
{
printf("SnmpRegister Failed. (%u)\n", SnmpGetLastError(hSession));
}
}
else
{
printf("SnmpCreateSession Failed. (%u)\n", SnmpGetLastError(NULL));
}
}
if (SNMPAPI_SUCCESS == statusStartup)
{
SnmpCleanup();
}
}
int _tmain(int argc, _TCHAR* argv[])
{
SnmpTest();
return 0;
}
I've tried other approach that uses the window notification.
But it didn't work.
I tried to verify this code with PowerShell event.
Opening evntwin, and adding PowerShell event.(ID:400/401/402/403)
To bring about trap event, I launched powershell and quit.
SNMP Service and Trap Sevice are runnning.
And the loop process in the above code is running.
But the sample program cannot receive any traps.
* Other manager such as Snmpb can receive traps.

set value to Excel cell in C++ throw exception 0x800A03EC

I'm writing an Excel Addin. One of a UDF in the addin is to set value to a selected cell by using Excel Automation in C++. In my code, I have no problem to get range, read value from selected cell, but when I try to set value to cell, if the value is a string, the code throw exception (0x80020005 Type mismatch), otherwise, it always throw exception with HResult 0x800A03EC. Below is a code snippet:
Any ideas?
void SetValue()
{
Excel::SheetsPtr pSheets = GetExcelApplicationObj()->GetWorksheets();
Excel::_WorksheetPtr pSheet = GetExcelApplicationObj()->GetActiveSheet();
_variant_t text = pSheet->Range["A2"]->Text; //Read value from selected cell works fine
pSheet->Range["C2"]->Value = "Hello"; // throw 0x80020005 Type mismatch
pSheet->Range["B2"]->Value = 5.0; //Set value throw Exception with HRESULT 0x800A03EC
}
Excel::_Application* GetExcelApplicationObj()
{
if (m_pApp == NULL)
{
std::vector<HWND>::iterator it;
std::vector<HWND> handles = getToplevelWindows();
for (it = handles.begin(); it != handles.end(); it++)
{
HWND hwndChild = NULL;
::EnumChildWindows( (*it), EnumChildProc, (LPARAM)&hwndChild);
if (hwndChild != NULL)
{
Excel::Window* pWindow = NULL;
HRESULT hr = ::AccessibleObjectFromWindow(hwndChild, OBJID_NATIVEOM, __uuidof(Excel::Window), (void**)&pWindow);
if (SUCCEEDED(hr))
{
if (pWindow != NULL)
{
m_pApp = pWindow->GetApplication();
pWindow->Release();
}
break;
}
}
}
}
return m_pApp;
}
std::vector<HWND> getToplevelWindows()
{
EnumWindowsCallbackArgs args( ::GetCurrentProcessId() );
if ( ::EnumWindows( &EnumWindowsCallback, (LPARAM) &args ) == FALSE ) {
return std::vector<HWND>();
}
return args.handles;
}
BOOL CALLBACK EnumWindowsCallback( HWND hnd, LPARAM lParam )
{
EnumWindowsCallbackArgs *args = (EnumWindowsCallbackArgs *)lParam;
DWORD windowPID;
(void)::GetWindowThreadProcessId( hnd, &windowPID );
if ( windowPID == args->pid ) {
args->handles.push_back( hnd );
}
return TRUE;
}
BOOL CALLBACK EnumChildProc(HWND hwndChild,LPARAM lParam)
{
CHAR className[128];
::GetClassName(hwndChild, className, 128);
if (strcmp(className, "EXCEL7") == 0)
{
HWND * phandle = (HWND*)lParam;
(*phandle) = hwndChild;
return FALSE;
}
return TRUE;
}
You have to wrap the string value into a variant.
Try this:
pSheet->Range["C2"]->Value = _variant_t(_bstr_t("Hello")).Detach();

Get Device using GUID always fails

I am attempting to get information(location info, location path, etc.) about a device that is currently connected to the computer in C++ Win32. I know how to get this information by using the function SetupDiGetDeviceRegistryProperty()
Before I use the function SetupDiGetDeviceRegistryProperty(), I must first call SetupDiGetSelectedDevice() because I need to pass a SP_DEVINFO_DATA as a parameter inside SetupDiGetDeviceRegistryProperty(). Is this correct?
My Problem: I can never get the device using the function SetupDiGetSelectedDevice(). When I call that function it always fails, ie, returns FALSE. GetLastError() returns the code e0000211 which I am not sure what that means.
Whats going wrong with my following code? If I am using the wrong function to get a device then what function do I use to get a device?
INT_PTR WINAPI WinProcCallback( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
switch (message)
{
case WM_DEVICECHANGE:
{
TCHAR strBuff[256];
PDEV_BROADCAST_HDR h = (PDEV_BROADCAST_HDR) lParam;
if (h->dbch_devicetype != DBT_DEVTYP_DEVICEINTERFACE) {
printf("h->dbch_devicetype != DBT_DEVTYP_DEVICEINTERFACE\n");
break;
}
switch (wParam)
{
case DBT_DEVICEARRIVAL:
{
DWORD dataT = 0;
SP_DEVINFO_DATA deviceInfoData = {0};
deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
deviceInfoData.ClassGuid = h->dbcc_classguid;
// The following function always works and is successful
HDEVINFO hDevInfo = SetupDiGetClassDevs(&h->dbcc_classguid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (hDevInfo == INVALID_HANDLE_VALUE) {
printf("hDevInfo == INVALID_HANDLE_VALUE\n");
break;
}
// ERROR OCCURS HERE: The following function ALWAYS returns false: whats going wrong?
if (SetupDiGetSelectedDevice(hDevInfo, &deviceInfoData) == FALSE) {
printf("SetupDiGetSelectedDevice(hDevInfo, &deviceInfoData) == FALSE\n");
break;
}
// Get device location information
DWORD buffersize = 0;
LPTSTR buffer = NULL;
while (!SetupDiGetDeviceRegistryProperty(hDevInfo, &deviceInfoData, SPDRP_LOCATION_INFORMATION, &dataT,
(PBYTE)buffer, buffersize, &buffersize))
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Change the buffer size.
if (buffer)
LocalFree(buffer);
buffer = (LPTSTR)LocalAlloc(LPTR, buffersize);
}
}
printf("Data: %d: %s\n", i, buffer);
}
break;