巨大八爪鱼 巨大八爪鱼
我喜欢做魔塔,更喜欢玩魔塔,尤其是大家用心血做的魔塔。
关注数: 650 粉丝数: 488 发帖数: 21,216 关注贴吧数: 303
C语言使用IXMLHttpRequest_put_onreadystatechange回调函数 第六节 使用IXMLHttpRequest_put_onreadystatechange回调函数处理Ajax异步请求 当IXMLHttpRequest设置成异步模式后,数据还没有接收完,IXMLHttpRequest_send函数就会提前返回。这样我们就需要用一个while循环来轮询IXMLHttpRequest_get_readyState的值,当ready_state=4时才表明数据接收完了,这时才能读取response回应内容。 在刚才的程序运行截图里面可以看得出来,“ready state: 1”打印了很长一串,这期间CPU一直在空转,这说明while循环的执行时间还是很长的。 为了解决这个问题,我们可以使用IXMLHttpRequest_put_onreadystatechange函数设置一个回调函数,每当ready_state的值发生变化时IXMLHttpRequest自动帮我们调用这个回调函数,我们在这个回调函数里面去读取response回应。 IXMLHttpRequest_put_onreadystatechange函数有两个参数,第一个参数是IXMLHttpRequest对象,第二个参数是我们自己定义的包含回调函数的IDispatch对象。也就是说我们要自己实现一个IDispatch对象。 刚才在第四节里面已经解释了IDispatch到底是个什么东西。IDispatch是一个根据函数名字符串调用函数的工具。IXMLHttpRequest_get_responseXML函数是IXMLHttpRequest给我们提供IDispatch对象,而现在我们使用IXMLHttpRequest_put_onreadystatechange函数,就要自己实现一个IDispatch对象传递给IXMLHttpRequest。 C语言实现COM接口的方法是建立一个自定义的结构体,这个结构体的第一个成员变量是要实现的接口的函数指针表的指针,其他成员可随便自定义。 函数指针表的类型名称是在接口名称后面加上Vtbl。我们要实现的是IDispatch接口,所以函数指针表的类型名为IDispatchVtbl。 struct xxx { IDispatchVtbl *pvtbl; …… (其他自定义成员) }; pvtbl成员变量是一个指针,一定要指向一个变量,通常把指向的这个变量也放到结构体里面,或者单独malloc出来也行。 (方法1) struct xxx { IDispatchVtbl *pvtbl; IDispatchVtbl vtbl; …… (其他自定义成员) }; struct xxx x; x.pvtbl = &x.vtbl; (方法2) struct xxx { IDispatchVtbl *pvtbl; …… (其他自定义成员) }; struct xxx x; x.pvtbl = malloc(sizeof(IDispatchVtbl))
C语言通过IShellLinkA创建或读取lnk快捷方式 /* 这个程序只能在C编译器下编译成功, 请确保源文件的扩展名为c */ #define COBJMACROS #include <stdio.h> #include <ShObjIdl.h> // char *字符串转wchar_t *字符串 wchar_t *gb2312_to_utf16(const char *s) { int n; wchar_t *ws; n = MultiByteToWideChar(CP_ACP, 0, s, -1, NULL, 0); ws = calloc(n, sizeof(wchar_t)); if (ws != NULL) MultiByteToWideChar(CP_ACP, 0, s, -1, ws, n); return ws; } // 创建快捷方式 void create_shortcut(const char *name, const char *target, const char *desc) { wchar_t *ws; IPersistFile *file; IShellLinkA *link; HRESULT hr; hr = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLinkA, &link); if (SUCCEEDED(hr)) { // 以下两个函数可直接传char *字符串 IShellLinkA_SetPath(link, target); IShellLinkA_SetDescription(link, desc); hr = IShellLinkA_QueryInterface(link, &IID_IPersistFile, &file); if (SUCCEEDED(hr)) { ws = gb2312_to_utf16(name); hr = IPersistFile_Save(file, ws, TRUE); // 第二个参数不是BSTR类型, 而是LPCOLESTR类型, 直接传wchar_t *字符串即可 // 第三个参数决定是否将此文件用作后续的工作文件 free(ws); if (SUCCEEDED(hr)) printf("创建快捷方式%s成功\n", name); else printf("创建快捷方式%s失败\n", name); IPersistFile_Release(file); } IShellLinkA_Release(link); } } // 解析快捷方式 void read_shortcut(const char *name) { char target[MAX_PATH]; // 在Windows系统中, 路径的最大长度是MAX_PATH char desc[INFOTIPSIZE]; // 在Windows系统中, 快捷方式描述的最大长度是INFOTIPSIZE wchar_t *ws; IPersistFile *file; IShellLinkA *link; HRESULT hr; hr = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLinkA, &link); if (SUCCEEDED(hr)) { hr = IShellLinkA_QueryInterface(link, &IID_IPersistFile, &file); if (SUCCEEDED(hr)) { ws = gb2312_to_utf16(name); hr = IPersistFile_Load(file, ws, STGM_READ); free(ws); if (SUCCEEDED(hr)) { printf("解析快捷方式%s成功\n", name); hr = IShellLinkA_GetPath(link, target, MAX_PATH, NULL, SLGP_RAWPATH); if (SUCCEEDED(hr)) printf("链接目标: %s\n", target); hr = IShellLinkA_GetDescription(link, desc, INFOTIPSIZE); if (SUCCEEDED(hr)) printf("描述: %s\n", desc); } else printf("解析快捷方式%s失败\n", name); IPersistFile_Release(file); } IShellLinkA_Release(link); } } // 解析开始菜单中Office 2010的所有快捷方式 void read_office2010_links() { char *folder = "C:\\Documents and Settings\\All Users\\「开始」菜单\\程序\\Microsoft Office"; char path[MAX_PATH]; HANDLE find; WIN32_FIND_DATAA find_data; // 请注意: _s结尾的字符串操作函数, 凡是命名为MaxCount的参数, 都要记得减去1, 否则字符数组刚好满的时候程序会崩溃 _snprintf_s(path, sizeof(path), sizeof(path) - 1, "%s\\*.lnk", folder); find = FindFirstFileA(path, &find_data); if (find != INVALID_HANDLE_VALUE) { do { _snprintf_s(path, sizeof(path), sizeof(path) - 1, "%s\\%s", folder, find_data.cFileName); read_shortcut(path); } while (FindNextFileA(find, &find_data)); FindClose(find); } } int main() { CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); create_shortcut("示例快捷方式.lnk", "C:\\WINDOWS\\system32\\shell32.dll", "Windows XP界面真好看啊!"); read_shortcut("示例快捷方式.lnk"); read_office2010_links(); CoUninitialize(); return 0;
首页 1 2 下一页