tag:blogger.com,1999:blog-34668988869740080052024-02-09T01:34:18.623+08:00No Geek Here!A blog about DirectShow, Network, and Windows Programming TechniquesUnknownnoreply@blogger.comBlogger57125tag:blogger.com,1999:blog-3466898886974008005.post-76965242323057439412009-10-21T08:46:00.000+08:002009-10-21T08:48:01.903+08:00DLL (Dynamic-Link Library) Search Order<i>Are you sure that your program loads the DLLs expected? You may want to check the search order for loading the proper DLLs.</i><br /><br /><b>Standard Search Order (SafeDllSearchMode is enabled)<br /></b>1. The directory from which the application loaded.<br />2. The system directory. Use the GetSystemDirectory function to get the path of this directory.<br />3. The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.<br />4. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.<br />5. The current directory.<br />6. The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.<br /><br /><b>More Detail Information</b><br /><a href="http://msdn.microsoft.com/en-us/library/ms682586.aspx">Dynamic-Link Library Search Order</a>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-3466898886974008005.post-49274385105877698612009-09-12T10:56:00.001+08:002009-09-12T10:58:49.029+08:00Mp4 Explorer<span style="font-weight:bold;">Brief Introdution</span><br />This software is a very helpful tool to inspect and see in details a mp4 file and it is open source. In my case, I was trying to write a program to convert certain video to be compatible with iPhone, but I had no idea about it. Then, I found this useful utility and used it to inspect the video structure of some compatible mp4 files.<br /><div style="text-align:center;"><br /><a href="http://www.flickr.com/photos/taigc/3901819629/" title="Flickr 上 Tai-Guang Chen 的 Mp4 Explorer"><img src="http://farm3.static.flickr.com/2421/3901819629_a10aa0d892_o.jpg" width="800" height="600" alt="Mp4 Explorer" /></a><br /></div><br />You can download the program and its source code in the following web site:<br /><br /><span style="font-weight:bold;">Official Website - Mp4 Explorer</span><br /><a href="http://mp4explorer.codeplex.com/">http://mp4explorer.codeplex.com/</a>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-3466898886974008005.post-33988713622750416072009-08-26T08:55:00.000+08:002009-08-26T08:58:28.638+08:00How To: Get the Content of Certain Environment Variable, ie: %ProgramFiles%<span style="font-weight:bold;">Code Snippet</span><br /><br />#include <windows.h><br />#include <string><br /><br />using namespace std;<br /><br />wstring GetContentFromEnvironmentVariable(const wstring& wstrVariable)<br />{<br /> // Get the content of %ProgramFiles%<br /><br /> wstring wstrRtn;<br /> DWORD dwSize = ::GetEnvironmentVariableW(wstrVariable.c_str(), NULL, NULL);<br /> if(dwSize > 0)<br /> {<br /> wchar_t* wszContent = new wchar_t [dwSize];<br /> dwSize = ::GetEnvironmentVariableW(wstrVariable.c_str(), wszContent, dwSize);<br /><br /> wstrRtn = wszContent;<br /><br /> delete [] wszContent;<br /> wszContent = NULL;<br /> }<br /><br /> return wstrRtn;<br />}<br /><br /><span style="font-weight:bold;">Reference on MSDN</span><br /><a href="http://msdn.microsoft.com/en-us/library/ms683188.aspx" target="_blank">GetEnvironmentVariable Function</a>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-3466898886974008005.post-11586514964756817182009-07-30T18:28:00.004+08:002009-07-30T18:32:32.910+08:00How To: Get the Installation Directory of Windows Media Player<div><b>Code Snippet</b></div><div><br /></div><span class="Apple-style-span" style="font-family:'courier new';">bool GetWMPInstallDirectory(wstring& wstrDirectory)<br />{<br /> bool bOK = false;<br /> HKEY hkResult = NULL;<br /><br /> LONG lRet = ::RegOpenKeyExW(HKEY_LOCAL_MACHINE,<br /> L"SOFTWARE\\Microsoft\\MediaPlayer", NULL, NULL, &hkResult);<br /><br /> if(lRet == ERROR_SUCCESS)<br /> {<br /> wchar_t wszRet[_MAX_PATH] = {0};<br /> DWORD type = REG_SZ;<br /> DWORD cbData = sizeof(wszRet);<br /><br /> lRet = ::RegQueryValueExW(hkResult, L"Installation Directory",<br /> NULL, &type, (LPBYTE)wszRet, &cbData);<br /><br /> if(lRet == ERROR_SUCCESS)<br /> {<br /> // We've got the installation directory of WMP<br /> wstrDirectory = wszRet;<br /> bOK = true;<br /> }<br /><br /> ::RegCloseKey(hkResult);<br /> hkResult = NULL;<br /> }<br /><br /> return bOK;<br />}</span>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-3466898886974008005.post-83553132547326877672009-06-12T09:20:00.003+08:002009-06-12T09:22:15.416+08:00How To: Disable General Protection Fault Dialog for Your Program<div><b>Abstraction</b></div><div>Are you using any 3rd-party componet or ActiveX, which is not stable enough, in your program? You will get a GPF dialog if the componet in your program goes abnormal. That is not your problem totally, but actually your program crashed. There's a Windows API to prevent showing GPF dialog, you may adapt this solution if the crash can be ignored.</div><div><br /></div><div><b>Code Snippet</b></div><div><br /></div><div><div><span class="Apple-style-span" style="font-family:'courier new';">UINT uPrevErrMode = SetErrorMode(SEM_NOGPFAULTERRORBOX);</span></div></div><div><br /></div><div><b>Do you not know what GPF is?</b></div><div><a href="http://nogeekhere.blogspot.com/2008/02/general-protection-fault.html">General Protection Fault</a></div><div><br /></div><div style="text-align:center;"><img src="http://farm3.static.flickr.com/2459/3599870992_9374f0f248_o.jpg" width="532" height="283" alt="Windows Calendar Crash" /><br /></div><div><br /></div><div><b>Reference on MSDN</b></div><div><div><a href="http://msdn.microsoft.com/en-us/library/ms680621.aspx" style="text-decoration: none;">SetErrorMode Function</a></div></div>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-3466898886974008005.post-38992018440824069922009-06-06T09:03:00.004+08:002009-06-06T09:11:36.019+08:00Read/Write Windows Registry on Windows 64-Bits Platforms (C# Version)<div><b>Abstraction</b></div><i>How does a 32-bits(x64) program running on Windows 64-bits(x64) access the 64-bits registry? In C#, you can use P/Invoke to call RegOpenKeyEx function with KEY_WOW64_KEY to access the 64-bits registry.<br /></i><br /><div><b>Code Snippet</b></div><div><br /><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#009900;">//<br />// This is a C# example to get the version of Windows Media Center on Windows 7 64-bits.<br />//</span><br />class RegQueryValueDemo<br />{<br /> [DllImport("advapi32.dll", CharSet = CharSet.Unicode, EntryPoint = "RegOpenKeyExW", SetLastError = true)]<br /> public static extern int RegOpenKeyEx(UIntPtr hKey, string subKey, uint options, int sam, out UIntPtr phkResult);<br /> public static UIntPtr HKEY_CURRENT_USER = (UIntPtr)0x80000001;<br /> public static UIntPtr HKEY_LOCAL_MACHINE = (UIntPtr)0x80000002;<br /> public static int KEY_QUERY_VALUE = 0x0001;<br /> public static int KEY_SET_VALUE = 0x0002;<br /> public static int KEY_CREATE_SUB_KEY = 0x0004;<br /> public static int KEY_ENUMERATE_SUB_KEYS = 0x0008;<br /> public static int KEY_WOW64_64KEY = 0x0100;<br /> public static int KEY_WOW64_32KEY = 0x0200;<br /><br /> [DllImport("advapi32.dll", CharSet = CharSet.Unicode, EntryPoint = "RegQueryValueExW", SetLastError = true)]<br /> public static extern int RegQueryValueEx(UIntPtr hKey, string lpValueName, int lpReserved, out uint lpType,<br /> StringBuilder lpData, ref int lpcbData);<br /><br /> public string GetMCEIdent()<br /> {<br /> UIntPtr regKeyHandle;<br /> if (RegOpenKeyEx(<br /> HKEY_LOCAL_MACHINE,<br /> "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Media Center",<br /> 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, out regKeyHandle) == 0)<br /> {<br /> uint type;<br /><br /> StringBuilder stringBuilder = new StringBuilder(2048);<br /> int cbData = stringBuilder.Capacity;<br /> if (RegQueryValueEx(regKeyHandle, "Ident", 0, out type, stringBuilder, ref cbData) == 0)<br /> {<br /> return stringBuilder.ToString();<br /> }<br /> }<br /><br /> return string.Empty;<br /> }<br />}</span><br /><br /><b>Find a C++ version?</b><br /><a href="http://nogeekhere.blogspot.com/2009/04/readwrite-windows-registry-on-windows.html">Read/Write Windows Registry on Windows 64-Bits Platforms</a><br /><br /><b>Reference on MSDN:</b><br /><a href="http://msdn.microsoft.com/en-us/library/ms724897.aspx">RegOpenKeyEx Function</a><br /><a href="http://msdn.microsoft.com/en-us/library/ms724072.aspx">32-bit and 64-bit Application Data in the Registry</a><br /></div>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-3466898886974008005.post-91045577783255499672009-05-24T23:22:00.001+08:002009-05-24T23:23:55.293+08:00How To: A Web Page Interacts with a Embedded Web Browser Control<div><i>If your application contains a web browser control to show certain web page, can the web page interact with your application by script language? Yes, it can. </i></div><div><br /></div><div>There's a sample on MSDN, it's very short but clear, please refer to the following link:</div><div><br /></div><div><b>Reference on MSDN</b></div><div><a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.webbrowser.objectforscripting.aspx" target="_blank">WebBrowser.ObjectForScripting Property</a></div><div><br /></div>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-3466898886974008005.post-62573383205314674972009-05-20T19:06:00.001+08:002009-05-24T23:16:43.807+08:00Windows Media ASF Viewer<span class="Apple-style-span" style="font-style: italic;">Windows Media® ASF Viewer 9 Series is a tool for inspecting the contents of files (such as .asf. .wma, and .wmv file) to make sure they meet the requirements of the Advanced Systems Format (ASF) specification. -- Microsoft</span><div><br /></div><div><div style="text-align:center;"><img src="http://farm4.static.flickr.com/3415/3547499083_c3e86db524_o.jpg" style="align:center" /></div><div style="text-align:center;"><br /></div><span class="Apple-style-span" style="font-weight: bold;">Brief Introduction</span><br /></div><div>This tool is very helpful for analyzing the contents of ASF files, it helps us to know the media structure and content easily. I was trying to encode WMV using Windows Media Format SDK, and this tool really helped me to verify the output content.</div><div><br /></div><div><span class="Apple-style-span" style="font-weight: bold;">Download from Microsoft</span></div><div><a href="http://www.microsoft.com/windows/windowsmedia/forpros/format/asfviewer.aspx">Windows Media ASF Viewer 9 Series</a></div>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-3466898886974008005.post-53626224563754448312009-05-14T23:15:00.003+08:002009-05-14T23:22:04.311+08:00How To: Extracting the embedded album art from a MP3 / WMA<span style="font-style:italic;">I'm using Windows Media Sync Reader in Windows Media Format SDK to get the album art from id3 tag of a MP3, it can also get from a WMA.</span><br /><br /><span style="font-weight:bold;">Code Snippet:</span><br /><br /><span class="Apple-style-span" style="font-family: 'courier new';">#include <windows.h><br />#include <wmsdk.h><br />#include <atlbase.h><br /><br />#pragma comment(lib, "wmvcore.lib")<br /><br />bool ExtractEmbeddedAlbumArt(LPCWSTR wszAudioFile)<br />{<br /> bool bOK = false;<br /><br /> WM_PICTURE* pPicture = NULL;;<br /><br /> do {<br /><br /> CComPtr<IWMSyncReader> pIWMSyncReader;<br /> if(FAILED(WMCreateSyncReader(NULL, 0, &pIWMSyncReader))) break;<br /><br /> if(FAILED(pIWMSyncReader->Open(wszAudioFile))) break;<br /><br /> CComPtr<IWMHeaderInfo3> pIWMHeaderInfo3;<br /> if(FAILED(pIWMSyncReader->QueryInterface(&pIWMHeaderInfo3))) break;<br /><br /> WMT_ATTR_DATATYPE wmtDataType = WMT_TYPE_BINARY;<br /> WORD wStreamNum = 0;<br /> WORD wLength = 0;<br /> if(FAILED(pIWMHeaderInfo3->GetAttributeByName(<br /> &wStreamNum, g_wszWMPicture, &wmtDataType, NULL, &wLength))) break;<br /><br /> pPicture = (WM_PICTURE*)new BYTE[wLength];<br /><br /> if(FAILED(pIWMHeaderInfo3->GetAttributeByName(<br /> &wStreamNum, g_wszWMPicture, &wmtDataType, (BYTE*)pPicture, &wLength))) break;<br /><br /> bOK = true;<br /><br /> } while(false);<br /><br /> if(pPicture)<br /> {<br /> //<br /> // TODO: Save the picture or do something with it<br /> //<br /><br /> delete [] (BYTE*)pPicture;<br /> pPicture = NULL;<br /> }<br /><br /> return bOK;<br />}</span>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-3466898886974008005.post-7549030256610006142009-04-28T21:27:00.002+08:002009-04-28T21:33:54.738+08:00How To: Handle dynamic format change in ReceiveConnection function on a renderer filter.<span class="Apple-style-span" style="font-style: italic;">I was trying to correctly handle dynamic format change on my video null renderer and had fought against it for several days.<br /><br />The following code snippet is my final work for handling dynamic format change, it seems to work fine, I hope so :p</span><br /><br /><span class="Apple-style-span" style="font-family: 'courier new';">STDMETHODIMP CNullRendererInputPin::ReceiveConnection(IPin * pConnector, const AM_MEDIA_TYPE *pmt)<br />{<br /> CAutoLock lock(m_pLock);<br /> <br /> CMediaType newMediaType(*pmt);<br /> <br /> HRESULT hr = E_FAIL;<br /><br /> if(m_Connected && m_Connected == pConnector && newMediaType != m_mt)<br /> {<br /> do {<br /><br /> hr = CheckMediaType(&newMediaType);<br /> if(FAILED(hr)) break;<br /><br /> BITMAPINFO bmpinfo = {0};<br /> if(FORMAT_VideoInfo == pmt->formattype && 1 == pmt->bFixedSizeSamples)<br /> {<br /> VIDEOINFOHEADER* t = (VIDEOINFOHEADER*)(pmt->pbFormat);<br /> bmpinfo.bmiHeader = t->bmiHeader;<br /> }<br /> else if(FORMAT_VideoInfo2 == pmt->formattype && 1 == pmt->bFixedSizeSamples)<br /> {<br /> VIDEOINFOHEADER2* t = (VIDEOINFOHEADER2*)(pmt->pbFormat);<br /> bmpinfo.bmiHeader = t->bmiHeader;<br /> }<br /> else<br /> {<br /> hr = E_UNEXPECTED;<br /> break;<br /> }<br /><br /> ALLOCATOR_PROPERTIES allocProperties = {0};<br /> {<br /> hr = m_pAllocator->GetProperties(&allocProperties);<br /> if(FAILED(hr)) break;<br /><br /> allocProperties.cbBuffer = bmpinfo.bmiHeader.biSizeImage;<br /> }<br /><br /> hr = SetMediaType(&newMediaType);<br /> if(FAILED(hr)) break;<br /><br /> hr = m_pAllocator->Decommit();<br /> if(FAILED(hr)) break;<br /><br /> {<br /> ALLOCATOR_PROPERTIES newAllocProperties = {0};<br /> hr = m_pAllocator->SetProperties(&allocProperties, &newAllocProperties);<br /> if(FAILED(hr)) break;<br /> }<br /><br /> hr = m_pAllocator->Commit();<br /> if(FAILED(hr)) break;<br /><br /> hr = S_OK;<br /><br /> } while(false);<br /> }<br /> else<br /> {<br /> hr = CBasePin::ReceiveConnection(pConnector, pmt);<br /> }<br /> <br /> return hr;<br />}</span>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-3466898886974008005.post-81036147123207592992009-04-15T22:25:00.003+08:002009-04-15T22:31:06.585+08:00Why will WCF client be disconnected after the connection idles for a long time?<i>The default receive timeout is 10 minutes, so WCF client will be disconnected after the idle time exceeded that limitation. What can I do if the connection needs to be kept alive?</i><br /><br /><b>Solution #1</b> - Server provides a dummy operation for client calls it regularly to let it not idle.<br /><br /><b>Solution #2</b> - Enable reliableSession and set receiveTimeout and inactivityTimeout to "infinite" in both the client and server.<br /><br />The configuration snippet may like the following:<br /><br /><div><span class="Apple-style-span" style="font-family:'courier new';"><system.serviceModel><br /> <bindings><br /> <wsHttpBinding><br /> <binding name="WSHttpBinding" receiveTimeout="infinite"><br /> <reliableSession inactivityTimeout="infinite" enabled="true" /><br /> </binding><br /> </wsHttpBinding><br /> </bindings><br /> <services><br /> ...<br /> </services><br /> ...<br /></system.serviceModel></span></div><br />You can get more detail explanation in the following reference link.<br /><br /><b>Reference in MSDN:</b><br /><a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.binding.receivetimeout.aspx">Binding.ReceiveTimeout Property</a><br /><br /><b>Reference in Paulo Reichert's Blog</b><br /><a href="http://blogs.conchango.com/pauloreichert/archive/2007/02/22/WCF-Reliable-Sessions-Puzzle.aspx">WCF Reliable Sessions Puzzle</a>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-3466898886974008005.post-81240753503866419822009-04-10T08:34:00.007+08:002009-04-10T08:59:16.069+08:00How To: Detect Windows Media Center Version<i>If your program is depending on a specified version of Windows Media Center, just try the following code to identify Windows Media Center versions.</i><br /><br /><b>Sample Code:</b><br /><br /><span class="Apple-style-span" style="font-family:'courier new';"><span class="Apple-style-span" style="color:#006600;font-weight:bold;">//<br />// Get Windows Media Center version from registry<br />// Function return false if no media center is installed on your windows<br />//<br />// Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Media Center<br />// Registry value name: Ident<br />// Registry value data type: REG_SZ<br />//</span><br />bool GetMediaCenterIdent(wstring& wstrIdent)<br />{<br /> bool bRtn = false;<br /><br /> HKEY hkResult = NULL;<br /> LONG lRetOpen = ::RegOpenKeyExW(<br /> HKEY_LOCAL_MACHINE,<br /> L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Media Center",<br /> NULL, KEY_READ, &hkResult);<br /><br /> if(lRetOpen == ERROR_SUCCESS)<br /> {<br /> WCHAR wszRet[2048] = {0};<br /> DWORD type_1 = REG_SZ;<br /> DWORD cbData = sizeof(wszRet);<br /><br /> LONG lRetQuery = ::RegQueryValueExW(hkResult, L"Ident", NULL,<br /> &type_1, (unsigned char *)wszRet, &cbData);<br /> if(lRetQuery == ERROR_SUCCESS)<br /> {<br /> wstrIdent = wszRet;<br /> bRtn = true;<br /> }<br /> }<br /><br /> if(hkResult)<br /> {<br /> ::RegCloseKey(hkResult);<br /> hkResult = NULL;<br /> }<br /><br /> return bRtn;<br />}<br /></span><br /><b>Ident value v.s Windows Media Center version</b><br /><br />< 2.7 = Windows XP Media Center Edition 2002<br />2.7 or 2.8 = Windows XP Media Center Edition 2004<br />3.0 = Windows XP Media Center Edition 2005<br />3.1 = Windows XP Media Center Edition 2005 with Update Rollup 1<br />4.0 = Windows XP Media Center Edition 2005 with Update Rollup 2<br />5.0 = Windows Vista<br />5.1 = Windows Vista with Media Center TV Pack 2008<br />6.0 = Windows 7 <br /><span><br /><b>Reference on MSDN:</b><br /><a href="http://msdn.microsoft.com/en-us/library/ms815274.aspx" target="_blank">Identifying Windows Media Center Versions</a><br /><br /></span>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-3466898886974008005.post-69430985233433455932009-04-06T19:04:00.008+08:002009-04-06T19:14:37.812+08:00How To: Determine whether a 32-bits application is running on Windows 64-bits platformWOW64 is the x86 emulator that allows 32-bit Windows-based applications to run seamlessly on 64-bit Windows.<br /><br /><span style="font-weight:bold;">Sample Code:</span><br /><span class="Apple-style-span" style="font-family:'courier new';"><br />bool IsRunningOnWow64()<br />{<br /> BOOL bIsWow64 = FALSE;<br /><br /> BOOL (WINAPI *fnIsWow64Process)(HANDLE, PBOOL);<br /> fnIsWow64Process = (BOOL(WINAPI*)(HANDLE, PBOOL))::GetProcAddress(<br /> ::GetModuleHandleW(L"kernel32"), "IsWow64Process");<br /><br /> if(NULL != fnIsWow64Process)<br /> fnIsWow64Process(GetCurrentProcess(), &bIsWow64);<br /><br /> return bIsWow64 ? true : false;<br />}<br /></span><br /><span style="font-weight:bold;">Reference on MSDN:</span><br /><a href="http://msdn.microsoft.com/en-us/library/ms684139.aspx" target="_blank">IsWow64Process Function</a><div><br /></div>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-3466898886974008005.post-60096174260090694672009-04-02T19:18:00.004+08:002009-06-05T08:11:17.686+08:00Read/Write Windows Registry on Windows 64-Bits PlatformsOn Windows Vista 64-bits, there's a 32-bits emulator called WOW64 for 32-bits applications. A 32-bits application running on WOW64 uses the registry redirector, because the 64-bit version of an application may use different registry keys and values than the 32-bit version.<br /><br />For 32-bits application:<br />On 64-bit platforms, it runs on WOW64 and accesses 32-bit registry (inside Wow6432Node).<br /><br />For 64-bits application:<br />On 64-bit platforms, it runs natively and accesses 64-bit registry (not inside Wow6432Node).<br /><br />Whatever, you can explicitly indicate which version of registry you want to access, just use RegOpenKeyEx function with KEY_WOW64_32KEY or KEY_WOW64_64KEY in the desired access rights parameter.<br /><br /><b>Example: A 32-bit application running on WOW64 accesses the 64-bit registry</b><br /><br /><span class="Apple-style-span" style="font-family:'courier new';">HKEY hkResult = NULL;<br />REGSAM samDesired = KEY_READ | KEY_WOW64_64KEY;<br />LONG lRetOpen = ::RegOpenKeyExW(<br /> HKEY_LOCAL_MACHINE,<br /> L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Media Center",<br /> NULL, samDesired, &hkResult);</span><br /><br /><b>Reference on MSDN:</b><br /><a href="http://msdn.microsoft.com/en-us/library/ms724072.aspx" target="_blank">32-bit and 64-bit Application Data in the Registry</a><div><br /></div>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-3466898886974008005.post-34994084533479279762009-03-10T22:15:00.002+08:002009-03-10T22:18:04.374+08:00Where can I find the list of installed ACM codecs on Vista?<div>It has moved to a strange place on Vista. Do the following steps to see the list:</div><div><br /></div><div>1. Click on Windows Media Player 11 -> Help -> About -> Technical Support Information</div><div><br /></div><div>2. It will generate "Support Information for Windows Media Player" and look under "Audio Codecs".</div><div><br /></div><div>You can also see the information about windows media player binaries and the list of video codecs.</div><div><br /></div><div>Reference:</div><div><a href="http://www.sagebrush.com/vista2.htm">Moving to Vista-- Part D'oh</a></div><div><br /></div>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-3466898886974008005.post-6321206866301998322009-03-04T22:31:00.002+08:002009-03-04T22:36:57.131+08:00error C3861: 'CoInitializeEx': identifier not found, even with argument-dependent lookup<div>You may get the following errors when trying to call CoInitializeEx(NULL, COINIT_MULTITHREADED).</div><div> </div><div><span class="Apple-style-span" style="font-style: italic;">error C2065: 'COINIT_MULTITHREADED' : undeclared identifier</span></div><div><span class="Apple-style-span" style="font-style: italic;">error C3861: 'CoInitializeEx': identifier not found, even with argument-dependent lookup</span></div><div><br /></div><div>The article in MSDN says "You must include the #define _WIN32_DCOM preprocessor directive at the beginning of your code to be able to use CoInitializeEx."</div><div><br /></div><div>Look at the code snap in ObjBase.h:</div><div><br /></div><div><span class="Apple-style-span" style="font-family:'courier new';">#if (_WIN32_WINNT >= 0x0400 ) || defined(_WIN32_DCOM) // DCOM</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'courier new';">WINOLEAPI CoInitializeEx(IN LPVOID pvReserved, IN DWORD dwCoInit);</span></div><div><span class="Apple-style-span" style="font-family:'courier new';">WINOLEAPI CoGetCallerTID( LPDWORD lpdwTID );</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'courier new';">#endif // DCOM</span></div><div><br /></div><div>So, you need to follow the above rule if you want to call CoInitializeEx, of course you also need to include <objbase.h>.</div><div><br /></div><div><span class="Apple-style-span" style="font-weight: bold;">Reference in MSDN:</span></div><div><span class="Apple-style-span" style="font-weight: bold;"><span class="Apple-style-span" style="font-weight: normal;"><a href="http://msdn.microsoft.com/en-us/library/ms695279.aspx" target="_blank">CoInitializeEx</a></span><br /></span></div><div><br /></div>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-3466898886974008005.post-9576911645079113542009-03-01T14:08:00.002+08:002009-03-01T14:11:21.451+08:00Why is the media sample upside down after convert its buffer data from YUV to RGB?<div><span class="Apple-style-span" style="font-weight: bold;">Question</span></div><div>I converted the buffer of a media sample from YUY2 to RGB24 pixel by pixel, and then I got a upside-down image. What's wrong with it?</div><div><br /></div><div><span class="Apple-style-span" style="font-weight: bold;">Answer</span></div><div>The definition of the biHeight field of BITMAPINFOHEADER depends the the biCompression field of BITMAPINFOHEADER.</div><div><br /></div><div>If the bitmap is uncompressed RGB format, the positive biHeight value means the image is bottom-up image; if the bitmap is one of YUV formats such as YUY2, UYVY, and YV12, the image is top-down oriented and the sign of biHeight value must be ignored.</div><div><br /></div><div>So, I need to do a vertical flip to get a correct image after convert buffer data from YUY2 to RGB24.</div><div><br /></div><div>You can get more detail information in FOURCC.org: <a href="http://www.fourcc.org/fccbihgt.php" target="_blank">Bitmap Orientation and biHeight</a></div><div><br /></div>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-3466898886974008005.post-1917953205751223612009-02-21T00:05:00.004+08:002009-02-21T00:25:46.580+08:00FORMAT_VideoInfo v.s. FORMAT_VideoInfo2<div><span class="Apple-style-span" style="font-style: italic;">If the media type is FORMAT_VideoInfo, it means the format buffer is a VIDEOINFOHEADER struct; if the media type is FORMAT_VideoInfo2, it means the format buffer is a VIDEOINFOHEADER2 struct. So, what's different between VIDEOINFOHEADER and VIDEOINFOHEADER2?</span></div><div><br /></div><div>VIDEOINFOHEADER and VIDEOINFOHEADER2 are very different, VIDEOINFOHEADER2 is not just an entended struct of VIDEOINFOHEADER. This means you cannot cast a pointer of VIDEOINFOHEADER2 to a pointer of VIDEOINFOHEADER.</div><div><br /></div><div><span class="Apple-style-span" style="font-weight: bold;">INCORRECT:</span><br /></div><div><br /></div><div><div>if(pmt->formattype == FORMAT_VideoInfo || pmt->formattype == FORMAT_VideoInfo2)</div><div>{</div><div> VIDEOINFOHEADER *pVIH = (VIDEOINFOHEADER*)pmt->pbFormat;</div><div> <span class="Apple-style-span" style="color: rgb(0, 102, 0);">// *** Wrong! ***</span></div><div>}</div><div><br /></div></div><div><span class="Apple-style-span" style="font-weight: bold;">CORRECT:</span></div><div><br /></div><div><div>if(pmt->formattype == FORMAT_VideoInfo)</div><div>{</div><div> VIDEOINFOHEADER *pVIH = (VIDEOINFOHEADER*)pmt->pbFormat;</div><div> <span class="Apple-style-span" style="color: rgb(0, 102, 0);">// Now you can use pVIH.</span></div><div>}</div><div>else if(pmt->formattype == FORMAT_VideoInfo2)</div><div>{</div><div> VIDEOINFOHEADER2 *pVIH = (VIDEOINFOHEADER2*)pmt->pbFormat;</div><div> <span class="Apple-style-span" style="color: rgb(0, 102, 0);">// Now you can use pVIH.</span></div><div>}</div><div><br /></div><div>Reference in MSDN:</div><div><a href="http://msdn.microsoft.com/en-us/library/dd407325.aspx" target="_blank">VIDEOINFOHEADER Structure</a><br /></div><div><a href="http://msdn.microsoft.com/en-us/library/dd407326.aspx" target="_blank">VIDEOINFOHEADER2 Structure</a><br /></div><div><br /></div></div>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-3466898886974008005.post-5886469274758229142009-02-17T23:12:00.004+08:002009-02-17T23:33:48.585+08:00How To: Toggle / Next Bookmark in Visual C++<span class="Apple-style-span" style="font-style: italic;">Bookmarking is a very useful feature of Visual C++ when you are coding, but the keyboard short cuts of this function is hard to remember. In the menu, you can find the short cuts of toggle and next bookmark are "Ctrl + K Ctrl +K" and "Ctrl + K Ctrl + N" respectively, but why do I need to press so many keys just for toggle or next bookmark?</span><div><div><br /></div><div>You can do it more easily, just use the following short cuts:</div><div><br /></div><div><div><span class="Apple-style-span" style="font-weight: bold;">Toggle Bookmark - Ctrl + F2</span></div><div><span class="Apple-style-span" style="font-weight: bold;"><br /></span></div><div><span class="Apple-style-span" style="font-weight: bold;">Next Bookmark - F2</span></div><div><br /></div><div>Wow! It is very easy to use, isn't it? Enjoy bookmarking feature during your coding time.</div><div><br /></div><div>I have tried it on Visual C++ 6 / 2003 / 2005 / 2008, it works fine.</div><div>(Note: The key mapping of Visual Studio is set to default "Visual C++".)</div><div><br /></div><div><span class="Apple-style-span" style="font-weight: bold;">Reference in This Site:</span></div><div><a href="http://nogeekhere.blogspot.com/2008/09/easiest-way-to-toggle-next-bookmark-in.html" targer="_blank">The easiest way to toggle / next bookmark in Visual Studio</a><br /></div><div><br /></div></div></div>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-3466898886974008005.post-39929284448437509282009-02-12T08:49:00.015+08:002009-02-12T13:15:38.255+08:00How To: STL String Case-insensitive Compare<span class="Apple-style-span" style="font-style: italic;">This article is talking about how to do a case-insensitive compare for STL string and wstring, there're 2 ways to reach the goal.</span><br /><br /><span class="Apple-style-span" style="font-weight: bold;">Method #1: C Run-time Library - _stricmp() and _wcsicmp()</span><br /><br /><span class="Apple-style-span" style="font-family:'courier new';">#include <string><br /><br />using namespace std;<br /><br />string strUpperCase = "ABC";<br />string strLowerCase = "abc";<br />if(_stricmp(strUpperCase.c_str(), strLowerCase.c_str()) == 0)<br /><span class="Apple-style-span" style="color: rgb(0, 102, 0);">// For wstring, use _wcsicmp() instead.</span><br />{<br /><span class="Apple-style-span" style="color: rgb(0, 102, 0);"> // Do something you need</span><br />}</span><br /><br /><span class="Apple-style-span" style="font-weight: bold;">Method #2: STL Algorithm - transform()</span><br /><br /><span class="Apple-style-span" style="font-family:'courier new';">#include <cctype><br />#include <string><br />#include <algorithm><br /><br />using namespace std;<br /><br /><span class="Apple-style-span" style="color: rgb(0, 102, 0);">// I make a helper function to compare string</span><br />bool CompareCaseInsensitive(string strFirst, string strSecond)<br />{<br /> <span class="Apple-style-span" style="color: rgb(0, 102, 0);">// Convert both strings to upper case by transfrom() before compare.</span><br /> transform(strFirst.begin(), strFirst.end(), strFirst.begin(), toupper);<br /> transform(strSecond.begin(), strSecond.end(), strSecond.begin(), toupper);<br /> if(strFirst == strSecond) return true; else return false;<br />}<br /><br />string strUpperCase = "ABC";<br />string strLowerCase = "abc";<br />if(CompareCaseInsensitive(strUpperCase, strLowerCase))<br />{<br /> <span class="Apple-style-span" style=""><span class="Apple-style-span" style="color: rgb(0, 102, 0);">// Do something you need</span></span><br />}</span><br /><br /><span class="Apple-style-span" style="font-weight: bold;">Reference in This Site:</span><br /><a href="http://nogeekhere.blogspot.com/2008/10/how-to-convert-stl-string-wstring-to.html" target="_blank">How to convert STL string / wstring to upper / lower case?</a><br /><br /><span class="Apple-style-span" style="font-weight: bold;">Reference in MSDN:</span><br /><a href="http://msdn.microsoft.com/en-us/library/k59z8dwe.aspx" target="_blank">_stricmp, _wcsicmp, _mbsicmp, _stricmp_l, _wcsicmp_l, _mbsicmp_l</a><div><br /></div>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-3466898886974008005.post-423930323218078532009-01-19T19:53:00.002+08:002009-01-19T19:55:44.225+08:00More explanation of CoInitialize() and CoUninitialize()<div>In this article, I'll not talk about how it works about the COM's apartment model, but the coding practice.<br /></div><div><br /></div><div>CoInitializeEx() provides the same functionality as CoInitialize() except it provides a parameter to specify the thread's apartment model. So, MSDN recommands us to call CoInitializeEx() instead of CoInitialize().</div><div><br /></div><div>For using CoInitializeEx(), we also need to follow the same rules as CoInitialize(), I mentioned in the previous article.</div><div><br /></div><div>The following examples explain how to use CoInitializeEx() and CoUninitialize():</div><div><br /></div><div><span class="Apple-style-span" style="font-weight: bold;">Example #1: CoInitializeEx() will return S_FALSE if the COM library was loaded.</span></div><div><br /></div><div><span class="Apple-style-span" style="font-family:'courier new';">void main()</span></div><div><span class="Apple-style-span" style="font-family:'courier new';">{</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> HRESULT hr = E_FAIL;</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> // The first call</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); // hr = S_OK</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> // The second call</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> hr = CoInitialize(NULL); // hr = S_FALSE, CoInitialize(NULL) = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> // ... skip ...</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> // For the second call</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> CoUninitialize();</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> // For the first call</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> CoUninitialize(); // COM library will be unloaded</span></div><div><span class="Apple-style-span" style="font-family:'courier new';">}</span></div><div><br /></div><div><span class="Apple-style-span" style="font-weight: bold;">Example #2: CoInitializeEx() will return RPC_E_CHANGED_MODE if a previous call to CoInitializeEx() specified a different apartment model</span></div><div><br /></div><div><span class="Apple-style-span" style="font-family:'courier new';">void main()</span></div><div><span class="Apple-style-span" style="font-family:'courier new';">{</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> HRESULT hr = E_FAIL;</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> // The first call</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); // hr = S_OK</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> // The second call</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); // hr = RPC_E_CHANGED_MODE, the thread's apartment model is still the single thread apartment.</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> // ... skip ...</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> // NOTE: We do not need to call CoUninitialize() if the corresponding call made by CoInitializeEx() returns error.</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> // For the first call</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> CoUninitialize(); // COM library will be unloaded</span></div><div><span class="Apple-style-span" style="font-family:'courier new';">}</span></div><div><br /></div>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-3466898886974008005.post-84747039247555296192009-01-18T22:25:00.003+08:002009-01-18T22:34:51.051+08:00A clear explanation of CoInitialize() and CoUninitialize()As you know, when you are using DirectShow or the other COM-based components, the first thing you have to do is calling CoInitialize() to initialize the COM library.<br /><br />Furthermore, there are several rules you should follow. Now, I will give you a clear explanation here.<br /><br /><span style="font-weight:bold;">Rule #1:</span> For each thread, you have to call CoInitialize() before you call any of the COM library funtions except CoGetMalloc() and the memory allocation functions.<br /><br /><span class="Apple-style-span" style="font-weight: bold;">Rule #2:</span> For each successful call made by CoInitialize(), you have to call CoUninitialize() to free the COM library.<br /><br /><span class="Apple-style-span" style="font-weight: bold;">Rule #3:</span> Do not call CoInitialize() or CoUninitialize() from the DllMain() function.<br /><br /><span class="Apple-style-span" style="font-weight: bold;">Rule #4: </span>The first thread in the application that calls CoInitialize() must be the last thread to call CoUninitialize().<br /><br /><br /><span class="Apple-style-span" style="font-weight: bold;">Reference in MSDN:</span><br /><a href="http://msdn.microsoft.com/en-us/library/ms678543.aspx" target="_blank">CoInitialize</a><div><br /></div>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-3466898886974008005.post-7579727173058606832009-01-15T08:46:00.002+08:002009-01-15T08:50:09.367+08:00fatal error RC1015: cannot open include file 'activex.ver'.<div><span class="Apple-style-span" style="font-weight: bold;">Error Message:</span></div><div><br /></div><div>fatal error RC1015: cannot open include file 'activex.ver'.</div><div><br /></div><div>When compile the DirectShow filter sample in DXSDK, you may get the above error message.</div><div><br /></div><div><span class="Apple-style-span" style="font-weight: bold;">Root Cause:</span></div><div><br /></div><div>The resource file(.rc) includes <activex.ver> and <activex.rcv>, but compiler cannot find them.</div><div><br /></div><div><span class="Apple-style-span" style="font-weight: bold;">Solution:</span></div><div><br /></div><div>activex.ver and activex.rcv are in %DXSDK%\Samples\C++\DirectShow\BaseClasses</div><div>(%DXSDK% is your dx sdk installed directory.)</div><div><br /></div><div>Add the above path to "VC++ Directories" of your VC++ setting,</div><div>or add it to "Additional Include Directories" of your project setting.</div><div><br /></div>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-3466898886974008005.post-84557808438112842142009-01-10T20:41:00.012+08:002009-01-10T21:01:51.407+08:00How to correctly call HttpOpenRequest() with specified accept types?<div><span class="Apple-style-span" style="font-weight: bold;">Windows API: (Wininet)</span><br /></div><div><br /></div><div><div><span class="Apple-style-span" style="font-family: 'courier new';">HINTERNET HttpOpenRequest(</span></div><div><span class="Apple-style-span" style="font-family: 'courier new';"> __in HINTERNET hConnect,</span></div><div><span class="Apple-style-span" style="font-family: 'courier new';"> __in LPCTSTR lpszVerb,</span></div><div><span class="Apple-style-span" style="font-family: 'courier new';"> __in LPCTSTR lpszObjectName,</span></div><div><span class="Apple-style-span" style="font-family: 'courier new';"> __in LPCTSTR lpszVersion,</span></div><div><span class="Apple-style-span" style="font-family: 'courier new';"> __in LPCTSTR lpszReferer,</span></div><div><span class="Apple-style-span" style="font-family: 'courier new';"> __in LPCTSTR *lplpszAcceptTypes,</span></div><div><span class="Apple-style-span" style="font-family: 'courier new';"> __in DWORD dwFlags,</span></div><div><span class="Apple-style-span" style="font-family: 'courier new';"> __in DWORD_PTR dwContext</span></div><div><span class="Apple-style-span" style="font-family: 'courier new';">);</span></div><div><br /></div><div><span class="Apple-style-span" style="font-weight: bold;">Tips:</span></div><div>lplpszAcceptTypes is not a pointer to a null-terminated string, it is a pointer to a null-terminated array of strings. </div><div><br /></div><div><span class="Apple-style-span" style="font-weight: bold;">Sample Code:</span></div><div><br /></div><div><span class="Apple-style-span" style="font-family: 'courier new';">// A null-terminated array of null-terminated strings</span></div><div><span class="Apple-style-span" style="font-family: 'courier new';">const char* lplpszAcceptTypes[] = {"text/*", NULL}; // Accept only text documents</span></div><div><span class="Apple-style-span" style="font-family: 'courier new';"><br /></span></div><div><div><span class="Apple-style-span" style="font-family: 'courier new';">HINTERNET hHttpFile = HttpOpenRequestA(</span></div><div><span class="Apple-style-span" style="font-family: 'courier new';"> hConnect,</span></div><div><span class="Apple-style-span" style="font-family: 'courier new';"> "GET",</span></div><div><span class="Apple-style-span" style="font-family: 'courier new';"> "/TextDocument",</span></div><div><span class="Apple-style-span" style="font-family: 'courier new';"> HTTP_VERSION,</span></div><div><span class="Apple-style-span" style="font-family: 'courier new';"> NULL,</span></div><div><span class="Apple-style-span" style="font-family: 'courier new';"> lplpszAcceptTypes,</span></div><div><span class="Apple-style-span" style="font-family: 'courier new';"> INTERNET_FLAG_DONT_CACHE, 1);</span></div><div><br /></div><div><span class="Apple-style-span" style="font-weight: bold;">Reference in MSDN:</span></div><div><a href="http://msdn.microsoft.com/en-us/library/aa384233.aspx" target="_blank">HttpOpenRequest Function</a></div><div><br /></div></div></div>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-3466898886974008005.post-42611532746742292442009-01-01T18:16:00.013+08:002009-01-10T14:45:22.041+08:00How to get the last modified date of a file in C++?On Win32 platform, you can get the attribute information of a file easily by just calling GetFileAttributesEx().<div>The information you got includes creation time, last access time, and last write time (last modified date).</div><div><br /></div><div><span class="Apple-style-span" style="font-weight: bold;">Windows API:</span></div><div><br /></div><div><div><span class="Apple-style-span" style="font-family:'courier new';">BOOL WINAPI GetFileAttributesEx(</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> __in LPCTSTR lpFileName,</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> __in GET_FILEEX_INFO_LEVELS fInfoLevelId,</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> __out LPVOID lpFileInformation</span></div><div><span class="Apple-style-span" style="font-family:'courier new';">);</span></div><div><br /></div><div><span class="Apple-style-span" style="font-weight: bold;">Sample Code:</span><br /></div><div><br /></div><div><span class="Apple-style-span" style="font-family:'courier new';">WIN32_FILE_ATTRIBUTE_DATA fileAttrData = {0};</span><br /></div><div><span class="Apple-style-span" style=" ;font-family:'courier new';">GetFileAttributesExW(L"C:\\abc.txt, </span><span class="Apple-style-span" style="font-family:'courier new';">GetFileExInfoStandard, &fileAttrData);</span></div><div><span class="Apple-style-span" style="font-family:'courier new';">// </span><span class="Apple-style-span" style=" ;font-family:'courier new';">GetFileAttributesExA for non-unicode</span><br /></div><div><span class="Apple-style-span" style="font-family:'courier new';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'courier new';">FILETIME ftLastModifiedDate = fileAttrData.ftLastWriteTime;<br /></span></div><div><br /></div><div><span class="Apple-style-span" style="font-weight: bold;">Reference in This Site:</span></div><div><a href="http://nogeekhere.blogspot.com/2007/12/systemtime-filetime-and-largeinteger.html">SYSTEMTIME, FILETIME, and LARGE_INTEGER</a><br /></div><div><a href="http://nogeekhere.blogspot.com/2008/11/what-happened-in-localfiletimetofiletim.html">What happened to LocalFileTimeToFileTime() / FileTimeToLocalFileTime()?</a><br /></div><div><br /></div><div><span class="Apple-style-span" style="font-weight: bold;">Reference in MSDN:</span><br /></div><div><span class="Apple-style-span" style="font-weight: bold;"><span class="Apple-style-span" style="font-weight: normal;"><a href="http://msdn.microsoft.com/en-us/library/aa364946.aspx" target="_blank">GetFileAttributesEx Function</a></span><br /></span></div><div><br /></div></div>Unknownnoreply@blogger.com