// QRCode.cpp : Implementation of CQRCode #include "stdafx.h" #include "QRCode.h" #include "..\QRCode\QR_Encode.h" // CQRCode STDMETHODIMP CQRCode::InterfaceSupportsErrorInfo(REFIID riid) { static const IID* arr[] = { &IID_IQRCode }; for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++) { if (InlineIsEqualGUID(*arr[i],riid)) return S_OK; } return S_FALSE; } STDMETHODIMP CQRCode::get_Text(BSTR* pVal) { *pVal = m_Text.AllocSysString(); return S_OK; } STDMETHODIMP CQRCode::put_Text(BSTR newVal) { m_Text = CString(newVal); return S_OK; } HRESULT CQRCode::StreamPNG(CxImage &img, VARIANT *ImageData, BOOL bPNG) { SAFEARRAY *psaData; BYTE *pData; SAFEARRAYBOUND rgsabound[1]; long size=0; BYTE* pBuffer=0; { { CmyTimer timer("CQRCode::StreamPNG/de PNG encoden"); if (!img.Encode(pBuffer,size, bPNG?CXIMAGE_FORMAT_PNG:CXIMAGE_FORMAT_GIF)) return myAtlReportError (GetObjectCLSID(), "\nStreamPNG encode failed: %s", img.GetLastError()); } // TODO: Echt netjes zou zijn om hier een IStream op te leveren? // create safe array and copy image data rgsabound[0].lLbound = 0; rgsabound[0].cElements = size; psaData = SafeArrayCreate(VT_UI1, 1, rgsabound); SafeArrayAccessData(psaData, (void **)&pData); memcpy(pData,pBuffer,size); SafeArrayUnaccessData(psaData); img.FreeMemory (pBuffer); // put data in variant ImageData->vt = (VT_ARRAY | VT_UI1); ImageData->parray = psaData; } myDoTRACE("\nCQRCode::StreamPNG done, sending %d bytes", size); return S_OK; } bool CQRCode::CreateCxImage(CxImage *img) { CQR_Encode* pQR_Encode = new CQR_Encode; BOOL res = pQR_Encode->EncodeData(m_nLevel, m_nVersion, m_bAutoExtend, m_nMaskingNo, m_Text ); if (!res) return false; img->Create((pQR_Encode->m_nSymbleSize+2*QR_MARGIN), (pQR_Encode->m_nSymbleSize+2*QR_MARGIN), 24 /* bpp */); img->Clear(m_BgGrayColor); img->SetTransIndex(-1); for (int i = 0; i < pQR_Encode->m_nSymbleSize; ++i) for (int j = 0; j < pQR_Encode->m_nSymbleSize; ++j) { if (pQR_Encode->m_byModuleData[i][j]) { img->SetPixelColor(i + QR_MARGIN, pQR_Encode->m_nSymbleSize - j + QR_MARGIN - 1, m_Color); } } img->Resample(m_nSize * img->GetWidth(), m_nSize * img->GetHeight()); delete pQR_Encode; return true; } STDMETHODIMP CQRCode::GetAsPNG(VARIANT* ImageData) { try { myDoTRACE("\nCQRCode::GetAsPNG()"); CxImage img; BOOL res = CreateCxImage(&img); if (!res) { CString err; err.Format("Could not QRCode: %s", m_Text); throw err; } return StreamPNG(img, ImageData, true /*bPNG*/); } catch (DWFException& ex) { CString err; err.Format("%ls\n%ls\n%s\n%ls(%d)",ex.type(),ex.message(),ex.function(),ex.file(),ex.line()); return myAtlReportError (GetObjectCLSID(), "\nCQRCode::GetAsPNG('%s')\n%s", m_Text, err); } catch (CString& err) { return myAtlReportError (GetObjectCLSID(), "\nCQRCode::GetAsPNG('%s')\n%s", m_Text, err); } return S_OK; } STDMETHODIMP CQRCode::get_Version(LONG* pVal) { *pVal = m_nVersion; return S_OK; } STDMETHODIMP CQRCode::put_Version(LONG newVal) { if (newVal < -1 || newVal > 40) return E_INVALIDARG; m_nVersion = newVal; return S_OK; } STDMETHODIMP CQRCode::get_Autoextend(VARIANT_BOOL* pVal) { *pVal = m_bAutoExtend; return S_OK; } STDMETHODIMP CQRCode::put_Autoextend(VARIANT_BOOL newVal) { m_bAutoExtend = newVal; return S_OK; } STDMETHODIMP CQRCode::get_Level(LONG* pVal) { *pVal = m_nLevel; return S_OK; } STDMETHODIMP CQRCode::put_Level(LONG newVal) { if (newVal < 1 || newVal > 3) return E_INVALIDARG; m_nLevel = newVal; return S_OK; } STDMETHODIMP CQRCode::get_Masking(LONG* pVal) { *pVal = m_nMaskingNo; return S_OK; } STDMETHODIMP CQRCode::put_Masking(LONG newVal) { if (newVal < -1 || newVal > 7) return E_INVALIDARG; m_nMaskingNo = newVal; return S_OK; } STDMETHODIMP CQRCode::get_Size(LONG* pVal) { *pVal = m_nSize; return S_OK; } STDMETHODIMP CQRCode::put_Size(LONG newVal) { if (newVal < 1 || newVal > 64) return E_INVALIDARG; m_nSize = newVal; return S_OK; } STDMETHODIMP CQRCode::get_Color(LONG* pVal) { *pVal = m_Color; return S_OK; } STDMETHODIMP CQRCode::put_Color(LONG newVal) { m_Color = newVal; return S_OK; } STDMETHODIMP CQRCode::get_BgGrayColor(BYTE* pVal) { *pVal = m_BgGrayColor; return S_OK; } STDMETHODIMP CQRCode::put_BgGrayColor(BYTE newVal) { m_BgGrayColor = newVal; return S_OK; }