void SettingsXML::ClearChildrenTail(IXMLDOMNode* apNode, IXMLDOMNode* apFirstClear) { HRESULT hr; IXMLDOMNode* pNext = NULL; IXMLDOMNode *pNodeRmv = NULL; DOMNodeType nodeType = NODE_INVALID; #ifdef _DEBUG BSTR bsDebug = NULL; if (pNext) { pNext->get_nodeType(&nodeType); pNext->get_xml(&bsDebug); } if (bsDebug) ::SysFreeString(bsDebug); bsDebug = NULL; #endif while (((hr = apFirstClear->get_nextSibling(&pNext)) == S_OK) && pNext) { pNext->get_nodeType(&nodeType); #ifdef _DEBUG pNext->get_xml(&bsDebug); if (bsDebug) ::SysFreeString(bsDebug); bsDebug = NULL; #endif hr = apNode->removeChild(pNext, &pNodeRmv); if (SUCCEEDED(hr) && (nodeType != NODE_TEXT)) SetDataChanged(); SafeRelease(pNodeRmv); SafeRelease(pNext); } apFirstClear->get_nodeType(&nodeType); hr = apNode->removeChild(apFirstClear, &pNodeRmv); if (SUCCEEDED(hr) && (nodeType != NODE_TEXT)) SetDataChanged(); SafeRelease(pNodeRmv); SafeRelease(apFirstClear); }
IXMLDOMNode *CXML::NextChildNode(IXMLDOMNode **ppNode) { if(!(*ppNode)) return NULL; IXMLDOMNode * pNode = NULL; IXMLDOMNodeList * pChildList = NULL; // Get the list of child nodes of the current node m_hr = (*ppNode)->get_childNodes(&pChildList); if (!SUCCEEDED(m_hr)) return NULL; // loop through the childs DOMNodeType nodeType; while(true) { // Get the node type of each child, if it is of NODE_ELEMENT type set it as current node m_hr = pChildList->nextNode(&pNode); if(!SUCCEEDED(m_hr)) { pChildList->Release(); return NULL; } if(!pNode) break; m_hr = pNode->get_nodeType(&nodeType); if(!SUCCEEDED(m_hr)) { pChildList->Release(); pNode->Release(); return NULL; } if(nodeType == NODE_ELEMENT) break; if(pNode) pNode->Release(); } if(pChildList) pChildList->Release(); return pNode; }
int DicomImageSet::insertFileItem(IXMLDOMDocument *pDom, IXMLDOMNode * pRoot, const QString &folderName, const QString &fileName) { DicomImage * dicomImage = new DicomImage (); if (!dicomImage->readHeader((QDir(folderName).absoluteFilePath(fileName)).toStdString().c_str())) { //fail to resolve header information return 0; } int nElement; char * patientsName = dicomImage->getCharTag(DicomImage::TAG_PATIENTS_NAME, nElement); char * patientsId = dicomImage->getCharTag(DicomImage::TAG_PATIENT_ID, nElement); char * protocolName = dicomImage->getCharTag(DicomImage::TAG_PROTOCOL_NAME, nElement); double * pInstanceNumber = dicomImage->getNumericTag(DicomImage::TAG_INSTANCE_NUMBER, nElement); double * pAcquisitionNumber = dicomImage->getNumericTag(DicomImage::TAG_ACQUISITION_NUMBER, nElement); double * pAcquisitionDate = dicomImage->getNumericTag(DicomImage::TAG_ACQUISITION_DATE, nElement); int instanceNumber = pInstanceNumber?(int)pInstanceNumber[0]:-1; int acquisitionNumber = pAcquisitionNumber?(int)pAcquisitionNumber[0]:-1; int acquisitionDate = pAcquisitionDate?(int)pAcquisitionDate[0]:0; IXMLDOMNode * pParent = findParentNode(pDom, pRoot, patientsName, patientsId, acquisitionDate, protocolName, acquisitionNumber); if (!pParent) { return 0; } HRESULT hr = S_OK; IXMLDOMElement *pNode = NULL; CHK_HR(CreateElement(pDom, L"File", &pNode)); CHK_HR(CreateAndAddAttributeNode(pDom, L"path", fileName.toStdWString().c_str(), pNode)); CHK_HR(CreateAndAddAttributeNode(pDom, L"instance_number", QString::number(instanceNumber).toStdWString().c_str(), pNode)); IXMLDOMNode * pSibling = NULL; CHK_HR(pParent->get_firstChild(&pSibling)); int sibInstanceNumber = -1; VARIANT varInstanceNumber; DOMNodeType nodeType; while (pSibling && instanceNumber >= sibInstanceNumber) { CHK_HR(pSibling->get_nodeType(&nodeType)); if(nodeType == NODE_ELEMENT) { CHK_HR(GetAttributeFromNode(pSibling, L"instance_number", &varInstanceNumber)); sibInstanceNumber = QString::fromWCharArray(_bstr_t(varInstanceNumber)).toInt(); if (instanceNumber < sibInstanceNumber) { break; } } IXMLDOMNode * tmpNode = NULL; CHK_HR(pSibling->get_nextSibling(&tmpNode)); SAFE_RELEASE(pSibling); pSibling = tmpNode; } if (pSibling) { IXMLDOMNode * tmpNode = NULL; CHK_HR(pSibling->get_previousSibling(&tmpNode)); SAFE_RELEASE(pSibling); pSibling = tmpNode; } CHK_HR(CreateAndAddTextNodeBefore(pDom, L"\n", pParent, pSibling)); CHK_HR(InsertChildToParent(pNode, pSibling, pParent)); CleanUp: SAFE_RELEASE(pNode); return 1; }
int DicomImageSet::readDatasetFile(const QString &datasetFileName, QTreeWidget *treeWidget) { HRESULT hr = S_OK; IXMLDOMDocument *pXMLDom = NULL; IXMLDOMNodeList *pPatients = NULL; IXMLDOMNode *pPatient = NULL; DOMNodeType nodeType; VARIANT_BOOL varStatus; VARIANT varFileName; VARIANT varValue; BSTR bstrQuery; VariantInit(&varFileName); VariantInit(&varValue); QString queryPatient, queryDate, queryProtocol, queryCollection; CHK_HR(CreateAndInitDOM(&pXMLDom)); CHK_HR(VariantFromString(datasetFileName.toStdWString().c_str(), varFileName)); CHK_HR(pXMLDom->load(varFileName, &varStatus)); if (varStatus != VARIANT_TRUE) { CHK_HR(ReportParseError(pXMLDom, "Failed to load DOM from stocks.xml.")); } treeWidget->clear(); treeWidget->setColumnCount(1); CHK_HR(pXMLDom->getElementsByTagName(L"Patient", &pPatients)); if (pPatients) { long nPatients; CHK_HR(pPatients->get_length(&nPatients)); for (long i=0; i<nPatients; ++i) { CHK_HR(pPatients->get_item(i, &pPatient)); CHK_HR(GetAttributeFromNode(pPatient, L"patients_name", &varValue)); queryPatient = QString::fromWCharArray(_bstr_t(varValue)); QTreeWidgetItem * patientItem = new QTreeWidgetItem(treeWidget, QStringList(queryPatient)); patientItem->setExpanded(true); IXMLDOMNodeList * pDates = NULL; CHK_HR(pPatient->get_childNodes(&pDates)); long nDates; CHK_HR(pDates->get_length(&nDates)); for (long j=0; j<nDates; ++j) { IXMLDOMNode * pDate = NULL; CHK_HR(pDates->get_item(j, &pDate)); CHK_HR(pDate->get_nodeType(&nodeType)); if(nodeType!=NODE_ELEMENT) { continue; } CHK_HR(GetAttributeFromNode(pDate, L"acquisition_date", &varValue)); queryDate = QString::fromWCharArray(_bstr_t(varValue)); int intDate = queryDate.toInt(); QDate date = (QDate::fromString("1900-01-01", "yyyy-MM-dd")).addDays(intDate-693962); QTreeWidgetItem * dateItem = new QTreeWidgetItem(patientItem, QStringList(date.toString("yyyy-MM-dd"))); dateItem->setExpanded(true); IXMLDOMNodeList * pProtocols = NULL; CHK_HR(pDate->get_childNodes(&pProtocols)); long nProtocols; CHK_HR(pProtocols->get_length(&nProtocols)); for (long j=0; j<nProtocols; ++j) { IXMLDOMNode * pProtocol = NULL; CHK_HR(pProtocols->get_item(j, &pProtocol)); CHK_HR(pProtocol->get_nodeType(&nodeType)); if(nodeType!=NODE_ELEMENT) { continue; } CHK_HR(GetAttributeFromNode(pProtocol, L"protocol_name", &varValue)); queryProtocol = QString::fromWCharArray(_bstr_t(varValue)); QTreeWidgetItem * protocolItem = new QTreeWidgetItem(dateItem, QStringList(queryProtocol)); protocolItem->setExpanded(true); IXMLDOMNodeList * pCollections = NULL; CHK_HR(pProtocol->get_childNodes(&pCollections)); long nCollections; CHK_HR(pCollections->get_length(&nCollections)); for (long j=0; j<nCollections; ++j) { IXMLDOMNode * pCollection = NULL; CHK_HR(pCollections->get_item(j, &pCollection)); CHK_HR(pCollection->get_nodeType(&nodeType)); if(nodeType!=NODE_ELEMENT) { continue; } CHK_HR(GetAttributeFromNode(pCollection, L"acquisition_number", &varValue)); queryCollection = QString::fromWCharArray(_bstr_t(varValue)); QTreeWidgetItem * collectionItem = new QTreeWidgetItem(protocolItem); QString queryStr = QString("root/Patient[@patients_name = '%1']/Date[@acquisition_date = '%2']/Protocol[@protocol_name = '%3']/Collection[@acquisition_number = '%4']") .arg(queryPatient).arg(queryDate).arg(queryProtocol).arg(queryCollection); IXMLDOMElement * pDtiNode = NULL; bstrQuery = SysAllocString(QString(queryStr+"/DTI").toStdWString().c_str()); CHK_ALLOC(bstrQuery); CHK_HR(pXMLDom->selectSingleNode(bstrQuery, (IXMLDOMNode**)&pDtiNode)); SysFreeString(bstrQuery); if (pDtiNode) { collectionItem->setText(0,queryCollection+"*"); } else { collectionItem->setText(0, queryCollection); } collectionItem->setData(0, Qt::UserRole, queryStr); collectionItem->setExpanded(true); protocolItem->addChild(collectionItem); SAFE_RELEASE(pCollection); } dateItem->addChild(protocolItem); SAFE_RELEASE(pProtocol); } patientItem->addChild(dateItem); SAFE_RELEASE(pDate); } treeWidget->insertTopLevelItem(i, patientItem); SAFE_RELEASE(pPatient); } } CleanUp: SAFE_RELEASE(pXMLDom); SAFE_RELEASE(pPatients); SAFE_RELEASE(pPatient); VariantClear(&varFileName); return SUCCEEDED(hr); }
/* Function name : CXML::ReplaceNodeText Description : This Helper function replaces the existing text with the given text of : the given node. Return type : bool Argument : IXMLDOMNode **pNode Argument : CString &rcsNodeText Tested : */ bool CXML::ReplaceNodeText(IXMLDOMNode **pNode,CString &rcsNodeText) { IXMLDOMText * pTextNode = NULL; if(!(*pNode)) return false; IXMLDOMNode * pTempNode = NULL; DOMNodeType nodeType; IXMLDOMNode * pINewNode = NULL; IXMLDOMNode * pIOldNode = NULL; IXMLDOMNodeList * pChildList = NULL; long nLen = 0,i=0; _bstr_t bstrData(rcsNodeText); m_hr = m_pXMLDoc->createTextNode(bstrData,&pTextNode); if(!SUCCEEDED(m_hr) || !pTextNode) goto on_Error; m_hr = (*pNode)->get_childNodes(&pChildList); if(!SUCCEEDED(m_hr) || !pChildList) goto on_Error; m_hr = pChildList->get_length(&nLen); if(!SUCCEEDED(m_hr)) goto on_Error; if(nLen == 0) // no childs, if the tag is empty { bool bRet = CreateNodeText(pNode,rcsNodeText); if(pChildList) pChildList->Release(); if(pTextNode) pTextNode->Release(); return bRet; } for(i =0; i< nLen;++i) { m_hr = pChildList->nextNode(&pTempNode); if(!SUCCEEDED(m_hr)) goto on_Error; m_hr = pTempNode->get_nodeType(&nodeType); if(!SUCCEEDED(m_hr)) goto on_Error; if(nodeType == NODE_TEXT) break; if(pTempNode) { pTempNode->Release(); pTempNode = NULL; } } m_hr = (*pNode)->replaceChild(pTextNode,pTempNode,&pINewNode); if(!SUCCEEDED(m_hr) || !pINewNode) goto on_Error; if(pChildList) pChildList->Release(); if(pTextNode) pTextNode->Release(); if(pINewNode) pINewNode->Release(); if(pTempNode) pTempNode->Release(); return true; on_Error: // Release all the References if(pChildList) pChildList->Release(); if(pTextNode) pTextNode->Release(); if(pINewNode) pINewNode->Release(); if(pTempNode) pTempNode->Release(); return false; }
bool CXML::NextChildNode() { if(!m_pICurrentNode) return false; IXMLDOMNode * pNode = NULL; IXMLDOMNode * pITempNode = m_pICurrentNode; pITempNode->AddRef(); IXMLDOMNodeList * pChildList = NULL; // Get the list of child nodes of the current node m_hr = pITempNode->get_childNodes(&pChildList); pITempNode->Release(); if (!SUCCEEDED(m_hr)) return false; // loop through the childs DOMNodeType nodeType; while(true) { // Get the node type of each child, if it is of NODE_ELEMENT type set it as current node m_hr = pChildList->nextNode(&pNode); if(!SUCCEEDED(m_hr)) { pChildList->Release(); return false; } if(!pNode) break; m_hr = pNode->get_nodeType(&nodeType); if(!SUCCEEDED(m_hr)) { pChildList->Release(); pNode->Release(); return false; } if(nodeType == NODE_ELEMENT) break; if(pNode) pNode->Release(); } if(pChildList) pChildList->Release(); if(pNode) { if(m_pICurrentNode) { m_pICurrentNode->Release(); m_pICurrentNode = NULL; } m_pICurrentNode = pNode; m_pICurrentNode->AddRef(); pNode->Release(); return true; } return false; }
bool SettingsXML::SetMultiLine(IXMLDOMNode* apNode, const wchar_t* asValue, long nAllLen) { bool bRc = false; HRESULT hr; VARIANT_BOOL bHasChild = VARIANT_FALSE; DOMNodeType nodeType = NODE_INVALID; BSTR bsNodeType = ::SysAllocString(L"line"); VARIANT vtType; vtType.vt = VT_I4; vtType.lVal = NODE_ELEMENT; IXMLDOMNode* pNode = NULL; IXMLDOMNode* pNodeRmv = NULL; long nLen = 0; const wchar_t* psz = asValue; bool bNewNodeCreate = false; int iAddIndent = 1; bool bAddFirstNewLine = false; hr = apNode->get_firstChild(&pNode); if (pNode == NULL) { bAddFirstNewLine = true; iAddIndent = mi_Level + 1; } // Обновляем существующие while ((psz && *psz && nAllLen > 0) && (SUCCEEDED(hr) && pNode)) { hr = pNode->get_nodeType(&nodeType); if (SUCCEEDED(hr) && (nodeType == NODE_ELEMENT)) { if (!SetAttr(pNode, L"data", psz)) goto wrap; nLen = _tcslen(psz)+1; psz += nLen; nAllLen -= nLen; } hr = pNode->get_nextSibling(&pNode); } // Добавляем что осталось while (psz && *psz && nAllLen > 0) { hr = mp_File->createNode(vtType, bsNodeType, L"", &pNode); if (FAILED(hr) || !pNode) goto wrap; if (!SetAttr(pNode, L"data", psz)) goto wrap; if (bAddFirstNewLine) { AppendNewLine(apNode); bAddFirstNewLine = false; } AppendIndent(apNode, iAddIndent); hr = apNode->appendChild(pNode, &pNodeRmv); AppendNewLine(apNode); bNewNodeCreate = true; iAddIndent = mi_Level + 1; SafeRelease(pNode); SafeRelease(pNodeRmv); if (FAILED(hr)) goto wrap; nLen = _tcslen(psz)+1; psz += nLen; nAllLen -= nLen; } // Очистить хвост (если элементов стало меньше) if (pNode) { ClearChildrenTail(apNode, pNode); AppendNewLine(apNode); bNewNodeCreate = true; } if (bNewNodeCreate) { AppendIndent(apNode, mi_Level); } bRc = true; wrap: _ASSERTE(nAllLen <= 1); ::SysFreeString(bsNodeType); return bRc; }
IXMLDOMNode* SettingsXML::FindItem(IXMLDOMNode* apFrom, const wchar_t* asType, const wchar_t* asName, bool abAllowCreate) { HRESULT hr = S_OK; IXMLDOMNodeList* pList = NULL; IXMLDOMNode* pChild = NULL; IXMLDOMNamedNodeMap* pAttrs = NULL; IXMLDOMAttribute *pIXMLDOMAttribute = NULL; IXMLDOMNode *pIXMLDOMNode = NULL; IXMLDOMNode *pName = NULL; BSTR bsText = NULL; BSTR bsCheck = NULL; DOMNodeType nodeTypeCheck = NODE_INVALID; BOOL lbEmpty = TRUE; int iLastIndent = 1; // Получить все дочерние элементы нужного типа if (apFrom == NULL) { hr = S_FALSE; } else { long lFound = 0; // key[@name="abc"], but it is case-sensitive, and may fails in theory bsText = lstrmerge(asType, L"[@name=\"", asName, L"\"]"); hr = apFrom->selectNodes(bsText, &pList); if (SUCCEEDED(hr) && pList) { hr = pList->get_length(&lFound); if (FAILED(hr) || (lFound < 1)) { SafeRelease(pList); } } SafeFree(bsText); // May be case-insensitive search will be succeeded? // However, it is very slow if (!pList) { bsText = ::SysAllocString(asType); hr = apFrom->selectNodes(bsText, &pList); ::SysFreeString(bsText); bsText = NULL; } } if (SUCCEEDED(hr) && pList) { hr = pList->reset(); while ((hr = pList->nextNode(&pIXMLDOMNode)) == S_OK && pIXMLDOMNode) { lbEmpty = FALSE; hr = pIXMLDOMNode->get_attributes(&pAttrs); if (SUCCEEDED(hr) && pAttrs) { bsText = GetAttr(pIXMLDOMNode, pAttrs, L"name"); if (bsText) { if (lstrcmpi(bsText, asName) == 0) { ::SysFreeString(bsText); bsText = NULL; pChild = pIXMLDOMNode; pIXMLDOMNode = NULL; break; } ::SysFreeString(bsText); bsText = NULL; } } pIXMLDOMNode->Release(); pIXMLDOMNode = NULL; } pList->Release(); //pList = NULL; -- для отладки } if (lbEmpty && abAllowCreate && (asType[0] == L'k')) { bsText = ::SysAllocString(L"value"); hr = apFrom->selectNodes(bsText, &pList); ::SysFreeString(bsText); bsText = NULL; if (SUCCEEDED(hr) && pList) { hr = pList->reset(); if ((hr = pList->nextNode(&pIXMLDOMNode)) == S_OK && pIXMLDOMNode) { lbEmpty = FALSE; pIXMLDOMNode->Release(); pIXMLDOMNode = NULL; } pList->Release(); //pList = NULL; -- для отладки } } if (!pChild && abAllowCreate) { if (asType[0] == L'k') { hr = apFrom->get_lastChild(&pChild); if (SUCCEEDED(hr) && pChild) { hr = pChild->get_nodeType(&nodeTypeCheck); if (SUCCEEDED(hr) && (nodeTypeCheck == NODE_TEXT)) { hr = pChild->get_text(&bsCheck); if (SUCCEEDED(hr) && bsCheck) { iLastIndent = 0; LPCWSTR pszTabs = bsCheck; while (*pszTabs) { if (*(pszTabs++) == L'\t') iLastIndent++; } ::SysFreeString(bsCheck); bsCheck = NULL; } } } SafeRelease(pChild); } VARIANT vtType; vtType.vt = VT_I4; vtType.lVal = NODE_ELEMENT; bsText = ::SysAllocString(asType); hr = mp_File->createNode(vtType, bsText, L"", &pChild); ::SysFreeString(bsText); bsText = NULL; if (SUCCEEDED(hr) && pChild) { if (SetAttr(pChild, L"name", asName)) { if (asType[0] == L'k') { AppendNewLine(pChild); mb_KeyEmpty = true; TouchKey(pChild); } if (asType[0] == L'k') { //if (mb_KeyEmpty) //AppendIndent(apFrom, lbEmpty ? (mi_Level-1) : mi_Level); AppendIndent(apFrom, (mi_Level-iLastIndent)); } else if (mb_KeyEmpty) { AppendIndent(apFrom, !lbEmpty ? (mi_Level-1) : mi_Level); } else { AppendIndent(apFrom, 1); } hr = apFrom->appendChild(pChild, &pIXMLDOMNode); pChild->Release(); pChild = NULL; if (FAILED(hr)) { pAttrs->Release(); pAttrs = NULL; } else { pChild = pIXMLDOMNode; pIXMLDOMNode = NULL; } AppendNewLine(apFrom); AppendIndent(apFrom, mi_Level-1); if ((asType[0] != L'k') && mb_KeyEmpty) mb_KeyEmpty = false; } else { pChild->Release(); pChild = NULL; } } } return pChild; }
static HRESULT ParseToolsList(IXMLDOMDocument* pXMLDom, BOOL bIsStandard) { static const _bstr_t XMLFileTag(L"MSCONFIGTOOLFILE"); static const _bstr_t XMLToolsTag(L"MSCONFIGTOOLS"); HRESULT hr = S_OK; IXMLDOMNode *pIterator = NULL, *pTmp = NULL; IXMLDOMElement* pEl = NULL; DOMNodeType type; _bstr_t tagName; if (!pXMLDom) return E_POINTER; // E_INVALIDARG pXMLDom->get_documentElement(&pEl); pEl->get_tagName(&tagName.GetBSTR()); _wcsupr(tagName); if (tagName == XMLFileTag) { pEl->get_firstChild(&pIterator); SAFE_RELEASE(pEl); while (pIterator) { pIterator->get_nodeType(&type); if (type == NODE_ELEMENT) { pIterator->QueryInterface(IID_PPV_ARG(IXMLDOMElement, &pEl) /* IID_PPV_ARGS(&pEl) */); pEl->get_tagName(&tagName.GetBSTR()); _wcsupr(tagName); if (tagName == XMLToolsTag) { pEl->get_firstChild(&pIterator); SAFE_RELEASE(pEl); while (pIterator) { pIterator->QueryInterface(IID_PPV_ARG(IXMLDOMElement, &pEl) /* IID_PPV_ARGS(&pEl) */); AddTool(pEl, bIsStandard); SAFE_RELEASE(pEl); pIterator->get_nextSibling(&pTmp); SAFE_RELEASE(pIterator); pIterator = pTmp; } // SAFE_RELEASE(pIterator); break; } SAFE_RELEASE(pEl); } pIterator->get_nextSibling(&pTmp); SAFE_RELEASE(pIterator); pIterator = pTmp; } // SAFE_RELEASE(pIterator); } else if (tagName == XMLToolsTag) { pEl->get_firstChild(&pIterator); SAFE_RELEASE(pEl); while (pIterator) { pIterator->QueryInterface(IID_PPV_ARG(IXMLDOMElement, &pEl) /* IID_PPV_ARGS(&pEl) */); AddTool(pEl, bIsStandard); SAFE_RELEASE(pEl); pIterator->get_nextSibling(&pTmp); SAFE_RELEASE(pIterator); pIterator = pTmp; } // SAFE_RELEASE(pIterator); } SAFE_RELEASE(pEl); return hr; }
//void SettingsXML::Save(const wchar_t *regName, const wchar_t *value) //{ // if (!value) value = L""; // сюда мог придти и NULL // // Save(regName, (LPCBYTE)value, REG_SZ, (_tcslen(value)+1)*sizeof(wchar_t)); //} void SettingsXML::Save(const wchar_t *regName, LPCBYTE value, DWORD nType, DWORD nSize) { HRESULT hr = S_OK; IXMLDOMNamedNodeMap* pAttrs = NULL; IXMLDOMNodeList* pList = NULL; IXMLDOMAttribute *pIXMLDOMAttribute = NULL; IXMLDOMNode *pNode = NULL; IXMLDOMNode* pChild = NULL; IXMLDOMNode *pNodeRmv = NULL; BSTR bsValue = NULL; BSTR bsType = NULL; bool bNeedSetType = false; // nType: // REG_DWORD: сохранение числа в 16-ричном или 10-чном формате, в зависимости от того, что сейчас указано в xml ("dword"/"ulong"/"long") // REG_BINARY: строго в hex (FF,FF,...) // REG_SZ: ASCIIZ строка, можно проконтролировать, чтобы nSize/2 не был меньше длины строки // REG_MULTI_SZ: ASCIIZZ. При формировании <list...> нужно убедиться, что мы не вылезли за пределы nSize pChild = FindItem(mp_Key, L"value", regName, true); // создать, если его еще нету if (!pChild) goto wrap; hr = pChild->get_attributes(&pAttrs); if (FAILED(hr) || !pAttrs) goto wrap; bsType = GetAttr(pChild, pAttrs, L"type"); switch(nType) { case REG_DWORD: { wchar_t szValue[32]; if (bsType && (bsType[0] == L'u' || bsType[0] == L'U')) { _wsprintf(szValue, SKIPLEN(countof(szValue)) L"%u", *(LPDWORD)value); } else if (bsType && (bsType[0] == L'l' || bsType[0] == L'L')) { _wsprintf(szValue, SKIPLEN(countof(szValue)) L"%i", *(int*)value); } else { _wsprintf(szValue, SKIPLEN(countof(szValue)) L"%08x", *(LPDWORD)value); if (bsType) ::SysFreeString(bsType); // нужно добавить/установить тип bsType = ::SysAllocString(L"dword"); bNeedSetType = true; } bsValue = ::SysAllocString(szValue); } break; case REG_BINARY: { if (nSize == 1 && bsType && (bsType[0] == L'u' || bsType[0] == L'U')) { wchar_t szValue[4]; BYTE bt = *value; _wsprintf(szValue, SKIPLEN(countof(szValue)) L"%u", (DWORD)bt); bsValue = ::SysAllocString(szValue); } else if (nSize == 1 && bsType && (bsType[0] == L'l' || bsType[0] == L'L')) { wchar_t szValue[4]; char bt = *value; _wsprintf(szValue, SKIPLEN(countof(szValue)) L"%i", (int)bt); bsValue = ::SysAllocString(szValue); } else { DWORD nLen = nSize*2 + (nSize-1); // по 2 символа на байт + ',' между ними bsValue = ::SysAllocStringLen(NULL, nLen); nLen ++; // Чтобы далее не добавлять WCHAR на '\0' wchar_t* psz = (wchar_t*)bsValue; LPCBYTE ptr = value; while(nSize) { _wsprintf(psz, SKIPLEN(nLen-(psz-bsValue)) L"%02x", (DWORD)*ptr); ptr++; nSize--; psz+=2; if (nSize) *(psz++) = L','; } if (bsType && lstrcmp(bsType, L"hex")) { // Допустим только "hex" ::SysFreeString(bsType); bsType = NULL; } if (!bsType) { // нужно добавить/установить тип bsType = ::SysAllocString(L"hex"); bNeedSetType = true; } } } break; case REG_SZ: { wchar_t* psz = (wchar_t*)value; bsValue = ::SysAllocString(psz); if (bsType && lstrcmp(bsType, L"string")) { // Допустим только "string" ::SysFreeString(bsType); bsType = NULL; } if (!bsType) { // нужно добавить/установить тип bsType = ::SysAllocString(L"string"); bNeedSetType = true; } } break; case REG_MULTI_SZ: { if (bsType && lstrcmp(bsType, L"multi")) { // Допустим только "multi" ::SysFreeString(bsType); bsType = NULL; } if (!bsType) { // нужно добавить/установить тип bsType = ::SysAllocString(L"multi"); bNeedSetType = true; } } break; default: goto wrap; // не поддерживается } if (bNeedSetType) { _ASSERTE(bsType!=NULL); SetAttr(pChild, pAttrs, L"type", bsType); ::SysFreeString(bsType); bsType = NULL; } // Теперь собственно значение if (nType != REG_MULTI_SZ) { _ASSERTE(bsValue != NULL); SetAttr(pChild, pAttrs, L"data", bsValue); ::SysFreeString(bsValue); bsValue = NULL; } else // Тут нужно формировать список элементов <list> { VARIANT_BOOL bHasChild = VARIANT_FALSE; DOMNodeType nodeType = NODE_INVALID; // Если ранее был параметр "data" - удалить его из списка атрибутов hr = pAttrs->getNamedItem(L"data", &pNode); if (SUCCEEDED(hr) && pNode) { hr = pChild->removeChild(pNode, &pNodeRmv); pNode->Release(); pNode = NULL; if (pNodeRmv) { pNodeRmv->Release(); pNodeRmv = NULL; } } //TODO: может оставить перевод строки? // Сначала почистим #ifdef _DEBUG hr = pChild->get_nodeType(&nodeType); #endif hr = pChild->hasChildNodes(&bHasChild); if (bHasChild) { while((hr = pChild->get_firstChild(&pNode)) == S_OK && pNode) { hr = pNode->get_nodeType(&nodeType); #ifdef _DEBUG BSTR bsDebug = NULL; pNode->get_text(&bsDebug); if (bsDebug) ::SysFreeString(bsDebug); bsDebug = NULL; #endif hr = pChild->removeChild(pNode, &pNodeRmv); if (pNodeRmv) { pNodeRmv->Release(); pNodeRmv = NULL; } pNode->Release(); pNode = NULL; } } // Теперь - добавляем список wchar_t* psz = (wchar_t*)value; BSTR bsNodeType = ::SysAllocString(L"line"); VARIANT vtType; vtType.vt = VT_I4; vtType.lVal = NODE_ELEMENT; long nAllLen = nSize/2; // длина в wchar_t long nLen = 0; while(psz && *psz && nAllLen > 0) { hr = mp_File->createNode(vtType, bsNodeType, L"", &pNode); if (FAILED(hr) || !pNode) break; if (!SetAttr(pNode, L"data", psz)) break; hr = pChild->appendChild(pNode, &pNodeRmv); pNode->Release(); pNode = NULL; if (pNodeRmv) { pNodeRmv->Release(); pNodeRmv = NULL; } if (FAILED(hr)) break; nLen = _tcslen(psz)+1; psz += nLen; nAllLen -= nLen; } _ASSERTE(nAllLen <= 1); } mb_Modified = true; wrap: if (pIXMLDOMAttribute) { pIXMLDOMAttribute->Release(); pIXMLDOMAttribute = NULL; } if (pNode) { pNode->Release(); pNode = NULL; } if (pNodeRmv) { pNodeRmv->Release(); pNodeRmv = NULL; } if (pChild) { pChild->Release(); pChild = NULL; } if (pAttrs) { pAttrs->Release(); pAttrs = NULL; } if (bsValue) { ::SysFreeString(bsValue); bsValue = NULL; } if (bsType) { ::SysFreeString(bsType); bsType = NULL; } }