WICPixelFormatGUID = {????????-????-????-????-????????????} gives on debugging - c++

I am trying to display on a button click. i have written a code and i am sure it is correct.
On debuging i get the value of WICPixelFormatGUID = {????????-????-????-????-????????????} and guidPixelFormatSource = {CCCCCCCC-CCCC-CCCC-CCCC-CCCCCCCCCCCC}. I don't know why i get these strange values??
My code is as follows-
HRESULT AMEPreviewHandler::ConvertBitmapSourceTo32bppHBITMAP(
IWICBitmapSource * pBitmapSource,
IWICImagingFactory * pImagingFactory,
HBITMAP * pStream)
//Pay Attention that this function is called from a static function by creating instance of the class (there is no problem in the function call . I have checked the value of the parameters while debugging and i am sure that its correct)
{
IWICBitmapSource *pBitmapSourceConverted = NULL;
WICPixelFormatGUID guidPixelFormatSource; /the problem here is here on debugging it gives strange value.
HRESULT hr = pBitmapSource->GetPixelFormat(&guidPixelFormatSource);
if (SUCCEEDED(hr) && (guidPixelFormatSource != GUID_WICPixelFormat32bppBGRA))
{
IWICFormatConverter *pFormatConverter;
hr = pImagingFactory->CreateFormatConverter(&pFormatConverter);
if (SUCCEEDED(hr))
{
.......And so on....
}
}
}
One more thing is when i run the same code from non-static function it works fine(but my situation is i have to call it on button click event and it is done by DialogProc()function (and it is static function) and i have no more option left so i created the instance of the class and using those instance and pointer i am calling this ConvertBitmapSourceTo32bppHBITMAP(by passing the parameter using instances which are intialized in contructor).
Any reasons for the strange value on debugging of the two ???

Related

Change div innerHTML through IHTMLDocument2 and C++

I'm trying to change the content of a div using IHTMLDocument2 interface this way:
IHTMLElementCollection* collection = NULL;
IDispatch* mydiv;
doc2->get_all(&collection);
long count;
collection->get_length(&count); //just to check I get something
CComVariant varstr = L"mydivname";
CComVariant varint = 0;
collection->item(varstr, varint, &mydiv); //this works I get the div
IHTMLElement* htmldiv;
mydiv->QueryInterface(IID_IHTMLElement, (void**)&htmldiv);
CComBSTR html;
htmldiv->get_innerHTML(&html); //works too, I get the current content
HRESULT hr=htmldiv->put_innerText(L"hello"); //this does not work but returns S_OK
collection->Release();
So the content of my div is just cleared and not replaced with "hello", I don't understand why, can it be a security issue ?
Thanks
According to the MSDN documentation, the string passed to put_innerText is of type BSTR.
So, I would suggest trying some code like this:
CComBSTR text(OLESTR("hello"));
hr = htmldiv->put_innerText(text);

TaskDialogIndirect is returning an unusual error code

I'm using TaskDialogIndirect to display prompts to the user. Normally this works just fine, but sometimes, after the program has been running for a while, it begins returning an error code that the MSDN entry does not list as being one of the error codes this function can return.
0x80040001 OLE_E_ADVF "Invalid advise flags"
I have checked all the inputs to the function against previous successful calls in the same run. Aside from differences in the string to be displayed, they are identical. (the strings are even the same length.)
// create task dialog struct
TASKDIALOGCONFIG tdc;
ZeroMemory(&tdc, sizeof(TASKDIALOGCONFIG));
tdc.cbSize = sizeof(tdc);
tdc.dwFlags = (((dwMessageBoxFlags & MB_OKCANCEL) == MB_OKCANCEL) ? TDF_ALLOW_DIALOG_CANCELLATION : 0) | TDF_POSITION_RELATIVE_TO_WINDOW;
tdc.hwndParent = hwndOwner;
tdc.hInstance = LGetHInstance();
tdc.pszContent = usrText.wsz;
tdc.pButtons = _pButtons;
tdc.cButtons = nButtons;
tdc.pszMainIcon = pszTaskDialogIcon;
tdc.pszWindowTitle = usrCaption.wsz;
tdc.nDefaultButton = nDefaultButton;
// display it now
int iButton = 0;
BOOL b = 0;
HRESULT hResult = TaskDialogIndirect(&tdc, &iButton, NULL, &b);
NEW INFORMATION
At the same time that TaskDialogIndirect stops behaving correctly, ShellExecute also stops working, as does CreateFile.
This was actually caused by an event handle leak elsewhere. When the available handles ran out, no more API calls which needed to create a handle could succeed. They did return a rather odd set of error codes though, none of which was "out of handles".

c++ MFC SDI DLL call method of OLE Server using IDispatch

I have written a c++ MFC DLL that brings up an SDI Application which is a very legacy OLE Server. (I have no choice about using this OLE Server so I have to make it work.)
I am accessing this c++ DLL from C#.
I have everything "working". I can call methods of the DLL, I have implemented C# delegates correctly, etc.
I can call methods of the OLE Server directly in C++ and export these so that my C# application call call them too. This is my "Hello World" for accessing the OLE Server functionality in its entirety from C#.
So far so good.
The next step is to make this C++ DLL as much of a "pass-through" as possible so that C# developers can write business logic around this OLE server. If changes or updates happen from the maker of the OLE Server, we do not want to have to update C++ code, we want to respond to the changes in C#.
So even though I can implement methods in C++ using the imported class from the OLEServer.tlb file and pass these through to C#, we do not want to ultimately do this. I am trying to call methods through the IDispatch interface instead and I am running into difficulties that I can't quite understand.
I am using Visual Studio 2010 for both unmanaged C++ and C#.
VARIANT LaserCat::LaserCatCommand(LPCTSTR* p_pMethodNameAndParamsInReverseOrder, UINT p_Count)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
VARIANT result;
VARIANT* pResult = NULL;
VariantInit(&result);
HRESULT hr = NULL;
DISPID dispid;
const IID IID_ITriad = {0x60EE772D,0xE076,0x4F58,{0xA8,0xB4,0x2F,0x7A,0x29,0xBB,0x02,0x50}};
COleException* pError = NULL;
BOOL HasDispatch = theApp.pTriadView->pTriadItem->Catalog.CreateDispatch(IID_ITriad, pError);
LPDISPATCH iDisp = theApp.pTriadView->pTriadItem->Catalog.m_lpDispatch;
LPOLESTR Names[1] = {(LPOLESTR)L"GetInterfaceVersion"};
hr = iDisp->GetIDsOfNames(IID_NULL, Names, 1, LOCALE_SYSTEM_DEFAULT, &dispid);
if (hr != S_OK) return result;
DISPPARAMS* pParams = new DISPPARAMS();
short maj = 0;
short min = 0;
short* nMajor = &maj;
short* nMinor = &min;
VARIANTARG Args[2];
VariantInit(&Args[0]);
VariantInit(&Args[1]);
Args[0].piVal = nMinor;
Args[0].vt = VT_BYREF;
Args[1].piVal = nMajor;
Args[1].vt = VT_BYREF;
pParams->rgvarg = Args;
pParams->cNamedArgs = 0;
pParams->cArgs = 2;
pParams->rgdispidNamedArgs = NULL;
EXCEPINFO* pExcept = NULL;
UINT* pArgErrorIndex = NULL;
LPCTSTR Error = NULL;
hr = iDisp->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, pParams, pResult, pExcept, pArgErrorIndex);
if (pExcept != NULL || pArgErrorIndex != NULL || hr != S_OK)
{
Error = _T("Error");
return result;
}
result = *pResult;
return result;
}
The following line from above gives me a "Bad variable type" error:
hr = iDisp->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, pParams, pResult, pExcept, pArgErrorIndex);
BTW, I am sure that the code can be vastly improved, it has been years since I have written in C++ and this is just a "first kick" at getting this working so no real error handling etc.
I have toyed around with "Args[]" type and value with variations of "Type Mismatch" errors and "Null Reference Pointers"
The function that is imported by the .tlb file looks like this:
short GetInterfaceVersion(short * nMajor, short * nMinor)
{
short result;
static BYTE parms[] = VTS_PI2 VTS_PI2 ;
InvokeHelper(0x178, DISPATCH_METHOD, VT_I2, (void*)&result, parms, nMajor, nMinor);
return result;
}
Oh, although I am passing in the "pMethodNameAndParamsInReverseOrder" as a parameter, I am just hard-coding it to get this one simple method working. Once I have it working with this and a few other methods, I am planning on making this generic to handle any methods implemented by the COM interface via IDispatch.
Any help would be appreciated mostly in getting this working but I would also appreciate any pointers on improving the code, I have mouch to learn in C++
Thank-You!
BTW, If this helps clarify things, theApp.pTriadView->pTriadItem->Catalog is the COM class I am implementing
EDIT:
Thanks to #HansPassant (see first comment) I see what I was missing. Unfortunately I have hit a downstream result of fixing that. The VARIANT "pResult" is coming back empty. I will continue to hunt that down now but any thoughts would be welcome :)

How to convert UnicodeString to BSTR?

I'm having a problem when calling OpenDatabase function (DAO). It's prototipe is:
virtual HRESULT STDMETHODCALLTYPE OpenDatabase(BSTR Name/*[in]*/, VARIANT Options/*[in,opt]*/,
VARIANT ReadOnly/*[in,opt]*/,
VARIANT Connect/*[in,opt]*/,
Dao_tlb::Database** ppDb/*[out,retval]*/) = 0; // [-1]
So, when I do this:
if(OpenDialog1->Execute() != true) return;
The selected filename is saved in OpenDialog1->FileName. Then I call the function above:
pDatabasePtr = pDBEngine->OpenDatabase(WideString(OpenDialog1->FileName).c_bstr(), myOpts, myRead, myCon);
and this works! But, the problem is when I try to set the filename to something else:
OpenDialog1->FileName = ParamStr(1); // OpenDatabase don't work in runtime - file not recognised!
or even set the filename inside a function:
pDatabasePtr = pDBEngine->OpenDatabase(WideString(L"SomeDB.mdb").c_bstr(), myOpts, myRead, myCon);
In both cases I get strange errors and never able to open a database. So, I probably convert UnicodeString/WideString to BSTR incorrectly.
So, why this function (OpenDatabase) works with
if(OpenDialog1->Execute() != true) return;
and does not work with
OpenDialog1->FileName = ParamStr(1);
How do I set the conversion correctly?
I found answer in here if anyone else needs it:
https://forums.embarcadero.com/thread.jspa?messageID=498776

Access sub object in COM interface

I want to get access to a sub object of a COM object. In my example I use the CANoe COM Server.
In my program I create a CAN interface to the CANoe Application. Here is an extract of my code so far and it does exactly what I want:
HRESULT result;
//prepare for COM handling...
result = CoInitialize(NULL);
//get CLSID of CANoe...
result = CLSIDFromProgID(L"CANoe.Application", &clsid);
if(SUCCEEDED(result))
{
//connect to COM interface of CANoe...
result = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER, IID_IApplication, (void**) &pIApp);
if(SUCCEEDED(result))
{
qDebug() << "COM connection established";
}
else
{
qDebug() << "COM connection error";
}
}
else
{
qDebug() << "Error: CLSID";
}
Now I want to get access to a sub object of the COM Server. For example the Measurement object. I tried it with the method pIApp->get_UI()
IDispatch* pIDis;
IMeasurement* pIMeasurement;
result = pIApp->get_UI(&pIDis);
pIMeasurement = (IMeasurement*) pIDis;
The pointer to the COM object needs to be a pointer of the type IMeasurement, so I can use all the methods defined in the header file. But the method get_UI only supports pointer of the type IDispatch. I tried to cast the pointer from type IDispatch to IMeasurement. But the program crashs at runtime.
I also tried to create a new interface directly to the sub object:
result = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER, IID_IMeasurement, (void**) &pIMeasurement);
But in this try in the variable result there is saved an error and I can't access the methods of the sub object Measurement.
Where is my mistake and how can I get access to the sub object?
Thank you for all answers and hints!
Thanks to #WhozCraig, #Hans Passant and #Eric Brown for the hints in the comments.
I was able to solve my problem with the following code:
IDispatch* pIDispatch;
//get pointer pIDispatch to Measurement object of CANoe...
result = pIApp->get_Measurement(&pIDispatch);
if(SUCCEEDED(result))
{
//pointer pIDispatch to pIMeasurement...
result = pIDispatch->QueryInterface(IID_IMeasurement, (void**) &pIMeasurement);
if(SUCCEEDED(result))
{
pIDispatch->Release();
//work with connection here...
pIMeasurement->Release();
}
}