【C語言調用Win32 COM組件】C語言通過COM創建快捷方式、設置Win7任務欄圖標進度條、使用MSXML6.0的IXMLDOMDocument讀取XML文件的方法

Win32下的COM組件其實也可以在不支持類的C語言裏面使用。


以下爲示例代碼。

/* 這個程序只能在C編譯器下編譯成功, 請確保源文件的擴展名爲c */
#define COBJMACROS
#include <MsXml6.h>
#include <stdio.h>
#include <ShlObj.h>
#include <Windows.h>

#pragma comment(lib, "msxml6.lib")

static HANDLE hThreads[3];

/* 創建快捷方式 */
static DWORD CALLBACK lnk_test(LPVOID lpParameter)
{
	HRESULT hr;
	IPersistFile *file;
	IShellLink *link;

	CoInitializeEx(NULL, COINIT_MULTITHREADED);
	hr = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLink, &link);
	if (SUCCEEDED(hr))
	{
		link->lpVtbl->SetPath(link, TEXT("C:\\Windows\\notepad.exe"));
		link->lpVtbl->SetDescription(link, TEXT("這是記事本"));
		hr = link->lpVtbl->QueryInterface(link, &IID_IPersistFile, &file);
		if (SUCCEEDED(hr))
		{
			IPersistFile_Save(file, L"記事本.lnk", TRUE);
			IPersistFile_Release(file);
		}
		link->lpVtbl->Release(link);
	}
	CoUninitialize();
	return 0;
}

/* 設置任務欄進度條 */
static DWORD CALLBACK taskbar_test(LPVOID lpParameter)
{
	int i;
	HWND hWnd;
	ITaskbarList3 *pTaskbar;

	CoInitializeEx(NULL, COINIT_MULTITHREADED);
	CoCreateInstance(&CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, &IID_ITaskbarList3, &pTaskbar);
	if (pTaskbar != NULL)
	{
		ITaskbarList3_HrInit(pTaskbar);
		hWnd = GetConsoleWindow();
		ITaskbarList3_SetProgressState(pTaskbar, hWnd, TBPF_NORMAL);
		for (i = 0; i <= 100; i += 20)
		{
			printf("[Taskbar] progress=%d%%\n", i);
			ITaskbarList3_SetProgressValue(pTaskbar, hWnd, i, 100);
			Sleep(250);
		}
		ITaskbarList3_Release(pTaskbar);
	}
	CoUninitialize();
	return 0;
}

/* 讀取XML文件 */
static void xml_display_attribute(IXMLDOMElement *element, const wchar_t *name, int isint)
{
	BSTR bstr;
	int num;
	VARIANT variant;

	bstr = SysAllocString(name);
	IXMLDOMElement_getAttribute(element, bstr, &variant);
	SysFreeString(bstr);

	printf("[Attribute] name=%ls, value=%ls", name, variant.bstrVal);
	if (isint)
	{
		num = _wtoi(variant.bstrVal);
		printf(", 2*value=%d", 2 * num);
	}
	printf("\n");
	SysFreeString(variant.bstrVal);
}

static void xml_display_elementcontent(IXMLDOMElement *node)
{
	BSTR bstr;

	IXMLDOMElement_get_text(node, &bstr);
	printf("[Text] %ls\n", bstr);
	SysFreeString(bstr);
}

static void xml_display_elementname(IXMLDOMElement *element)
{
	BSTR bstr;

	IXMLDOMElement_get_nodeName(element, &bstr);
	printf("[Node] name=%ls\n", bstr);
	SysFreeString(bstr);
}

static void xml_display_elementinnerxml(IXMLDOMElement *element)
{
	BSTR bstr;

	IXMLDOMElement_get_xml(element, &bstr);
	printf("[InnerXML] %ls\n", bstr);
	SysFreeString(bstr);
}

// Element其實是Node的子類
// Node是節點, 而Element是元素節點
static void xml_display_nodecontent(IXMLDOMNode *node)
{
	BSTR bstr;

	IXMLDOMNode_get_text(node, &bstr);
	printf("[Text] %ls\n", bstr);
	SysFreeString(bstr);
}

static void xml_display_nodename(IXMLDOMNode *node)
{
	BSTR bstr;

	IXMLDOMNode_get_nodeName(node, &bstr);
	printf("[Node] name=%ls\n", bstr);
	SysFreeString(bstr);
}

static void xml_read(IXMLDOMDocument *xmldoc)
{
	long i, len;
	IXMLDOMElement *root, *element;
	IXMLDOMNode *node;
	IXMLDOMNodeList *list;

	IXMLDOMDocument_get_documentElement(xmldoc, &root);
	xml_display_elementname(root);
	xml_display_attribute(root, L"id", 1);
	xml_display_elementinnerxml(root);
	printf("\n");

	IXMLDOMElement_get_childNodes(root, &list);
	IXMLDOMNodeList_get_length(list, &len);
	for (i = 0; i < len; i++)
	{
		IXMLDOMNodeList_get_item(list, i, &node);
		xml_display_nodename(node);
		xml_display_nodecontent(node);

		IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, &element); // node轉element
		xml_display_attribute(element, L"name", 0);
		IXMLDOMElement_Release(element);

		IXMLDOMNode_Release(node);
		printf("\n");
	}

	IXMLDOMElement_Release(root);
}

static DWORD CALLBACK xml_test(LPVOID lpParameter)
{
	BSTR bstr;
	HRESULT hr;
	IXMLDOMDocument *xmldoc;
	VARIANT_BOOL flag;

	CoInitializeEx(NULL, COINIT_MULTITHREADED);
	hr = CoCreateInstance(&CLSID_DOMDocument60, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, &xmldoc);
	if (SUCCEEDED(hr))
	{
		bstr = SysAllocString(L"<?xml version=\"1.0\" encoding=\"utf-8\"?><data id=\"105\"><book name=\"haha\">abcd</book><book name=\"hoho\">efgh</book></data>");
		IXMLDOMDocument_loadXML(xmldoc, bstr, &flag);
		SysFreeString(bstr);
		if (flag == VARIANT_TRUE)
			xml_read(xmldoc);
		IXMLDOMDocument_Release(xmldoc);
	}
	CoUninitialize();
	return 0;
}

int main(void)
{
	hThreads[0] = CreateThread(NULL, 0, lnk_test, NULL, 0, NULL);
	hThreads[1] = CreateThread(NULL, 0, taskbar_test, NULL, 0, NULL);
	hThreads[2] = CreateThread(NULL, 0, xml_test, NULL, 0, NULL);

	WaitForMultipleObjects(_countof(hThreads), hThreads, TRUE, INFINITE);
	return 0;
}

程序運行結果:

[Node] name=data
[Attribute] name=id, value=105, 2*value=210
[InnerXML] <data id="105"><book name="haha">abcd</book><book name="hoho">efgh</b
ook></data>

[Node] name=book
[Text] abcd
[Attribute] name=name, value=haha

[Node] name=book
[Text] efgh
[Attribute] name=name, value=hoho

[Taskbar] progress=0%
[Taskbar] progress=20%
[Taskbar] progress=40%
[Taskbar] progress=60%
[Taskbar] progress=80%
[Taskbar] progress=100%

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章