2010年3月6日 星期六

How to read XML file

Parsing XML
/********************Code****************************/

#include

#include
TCHAR szCountryName[MAX_LOADSTRING];
int nCurMCC;
int nProc;
int nCountryPos = -1, nCountryIndex = -1, nOldPos = -1;
int nOperatorPos = -1, nOperatorIndex = -1;
COperatorLinkList *OperatorList;

void ProcessNode(IXMLDOMNode *lpNode)
{
IXMLDOMNamedNodeMap *pAttr; // xml 的屬性列表
IXMLDOMNodeList *pNodeList; // xml節點列表接口
IXMLDOMNode *pNode; // xml節點接口
BSTR name, bstrAttrName;
VARIANT value, varAttrValue;
TCHAR szText[MAX_LOADSTRING], szText1[MAX_LOADSTRING];
LPWSTR lpStr;
long len;
int nCurMNC;
TypeConfigInfo *pTempConfigList;
COperatorLinkList *OperatorListTmp = new COperatorLinkList;

lpNode->get_nodeName(&name); // 得到節點名稱,也就是TAG
lpNode->get_nodeValue(&value); // 得到節點值
lpNode->get_attributes(&pAttr); // 得到節點屬性列表
pAttr->get_length(&len);
for(int i = 0; i <>get_item(i, &pNode); // 得到屬性列表中的一個屬性節點
pNode->get_nodeName(&bstrAttrName); // 得到屬性名
pNode->get_nodeValue(&varAttrValue); // 得到屬性值
lpStr = (LPWSTR)name;

if((wcscmp(lpStr, TEXT("entry"))) == 0)
{
nProc = 2;
switch (i)
{
case 0:
lpStr = (LPWSTR)varAttrValue.bstrVal;
nCurMNC = _wtoi(lpStr);
nOperatorPos++;
nOperatorIndex++;
break;
case 1:
lpStr = (LPWSTR)varAttrValue.bstrVal;
wcscpy(szText, lpStr);
break;
case 2:
lpStr = (LPWSTR)varAttrValue.bstrVal;
wcscpy(szText1, lpStr);
break;
}
}
else if(wcscmp(lpStr, TEXT("country")) == 0)
{
nProc = 1;
switch (i)
{
case 0:
lpStr = (LPWSTR)varAttrValue.bstrVal;
wcscpy(szCountryName, lpStr);
nCountryPos++;
nCountryIndex++;
break;
case 1:
lpStr = (LPWSTR)varAttrValue.bstrVal;
nCurMCC = _wtoi(lpStr);
nOperatorPos = -1;
nOperatorIndex = -1;
break;
}
}

}

if(nProc == 2) //先確定有Operator了才新增,
{
if(nOperatorPos != 0)
{
if(OperatorListTmp)
delete OperatorListTmp; //不是新的國家就刪除,延用舊的,一筆一筆接下去

if((wcscmp(szText1, TEXT(""))) == 0)
nOperatorIndex--;

OperatorList->Add(nOperatorPos, nOperatorIndex, nCurMCC, nCurMNC, szText, szText1);
}
else
{
if(OperatorListTmp != NULL)
{
OperatorList = OperatorListTmp; //是新的國家
pTempConfigList = OperatorList->Add(nOperatorPos, nOperatorIndex, nCurMCC, nCurMNC, szText, szText1);
if(nCountryPos != nOldPos)
{
CountryList.Add(nCountryPos, nCountryIndex, szCountryName, pTempConfigList);
nOldPos = nCountryPos;
}
}
}
}

lpNode->get_childNodes(&pNodeList); // 得到節點的字節點列表
pNodeList->get_length(&len);
for(int j = 0; j <>get_item(j, &pNode);
ProcessNode(pNode); // 遞回處理下層節點
}
}

VARIANT VariantString(BSTR str)
{
VARIANT var;
VariantInit(&var);
V_BSTR(&var) = SysAllocString(str);
V_VT(&var) = VT_BSTR;
return var;
}

BOOL LoadCountries()
{
IXMLDOMDocument *pXMLDom = NULL;
IXMLDOMNodeList *pNodes = NULL;
IXMLDOMNode *pNode = NULL;
BSTR bstr = NULL;
VARIANT_BOOL status;
VARIANT var;
HRESULT hr;
long length;

CoInitializeEx(NULL, COINIT_MULTITHREADED);
hr = CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument, (void **) &pXMLDom);
hr = pXMLDom->put_async(VARIANT_FALSE);
hr = pXMLDom->put_validateOnParse(VARIANT_FALSE);
hr = pXMLDom->put_resolveExternals(VARIANT_FALSE);

if (!pXMLDom)
goto clean;

VariantInit(&var);
var = VariantString(XML_PATH);
hr = pXMLDom->load(var, &status);

if (status != VARIANT_TRUE)
goto clean;


IXMLDOMElement *pElem; // xml元素接口
IXMLDOMNodeList *pNodeList; // xml節點列表接口

pXMLDom->get_documentElement(&pElem); // 得到xml文檔的根,就是上面的xml的Root節點
pElem->get_childNodes(&pNodeList); // 得到root的子節點列表
pNodeList->get_length(&length); // 得到root的子節點數量
for(int i = 0; i <>get_item(i, &pNode); // 得到一個字節點
ProcessNode(pNode); // 調用處理函數處理
}

return TRUE;

clean:
if (bstr)
SysFreeString(bstr);
if (&var)
VariantClear(&var);
if (pXMLDom)
pXMLDom->Release();
if (pNodes)
pNodes->Release();
if (pNode)
pNode->Release();

CoUninitialize();
return FALSE;
}
/********************Code****************************/



XML sample
/********************XML sample**********************/



/********************XML sample**********************/

2010年3月4日 星期四

ListView sort item at anytime

ListView_SortItems可以用來排序,但只能在按在column時進來排序, 在其它時間點即便call ListView_SortItems(hwnd, CompareFunc, lParamSort), 在CompareFunc callback function中的lParam1, lParam2也會是NULL.
int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);

所以,你如果想利用ListView的ListView_SortItems來進行排序卻又不想受限,就模擬OS的message loop,模擬按下ListView的clomun,就能在任何時間點進行sort.

//------------------------------Code-----------------------------------
int nColumnWidth[3]; //假設有3個column
for(int i = 0 ; i < 3; i++)
nColumnWidth[i] = ListView_GetColumnWidth(g_hwndLV, i);

DWORD dwPos = 0;

for(int i = 0; i < g_nSortColumn; i++)
dwPos = dwPos + nColumnWidth[i];

dwPos = dwPos + (nColumnWidth[g_nSortColumn] / 2) + SORT_POS_Y; // SORT_POS_Y的值為0x00140000

HWND hWndListViewHeader = ListView_GetHeader(g_hwndLV);
PostMessage(hWndListViewHeader, WM_SETCURSOR, (WPARAM)hWndListViewHeader, 0x02010001); //lParam固定為0x02010001
PostMessage(hWndListViewHeader, WM_LBUTTONDOWN, 0X00000001, dwPos); // wParam 固定為0X00000001
PostMessage(hWndListViewHeader, WM_LBUTTONUP, 0X00000001, dwPos);


//------------------------------Code-----------------------------------

dwPos 的算法為4個bit一個數字,前4個bit代表Y,後4個bit代表X, 0X0014006A代表座標X:106, Y:20