### DllInstall Source: https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/ Handles installation and setup for a DLL. ```APIDOC ## DllInstall ### Description Handles installation and setup for a DLL. ### Function DllInstall ### Parameters - **bInstall** (BOOL) - TRUE to install, FALSE to uninstall. - **pszCmdLine** (PCWSTR) - Command line arguments. ``` -------------------------------- ### regsvr32 command to install a DLL with DllInstall Source: https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-dllinstall Command-line example that invokes regsvr32 with the /i flag and a string to install a DLL. The string is passed as the pszCmdLine parameter to DllInstall, with bInstall set to TRUE. ```plaintext regsvr32 /i:"Install_1" dllname.dll ``` -------------------------------- ### DllInstall function Source: https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-dllinstall Handles installation and setup for a DLL. It is invoked by regsvr32 to allow the DLL to perform tasks such as adding information to the registry. ```APIDOC ## DllInstall function ### Description Handles installation and setup for a DLL. It is invoked by regsvr32 to allow the DLL to perform tasks such as adding information to the registry. ### Syntax ```cpp HRESULT DllInstall( BOOL bInstall, [in, optional] PCWSTR pszCmdLine ); ``` ### Parameters - **bInstall** (BOOL) - Required - **TRUE** if the DLL is being installed; **FALSE** if it is being uninstalled. - **pszCmdLine** (PCWSTR) - Optional - A string passed in by **regsvr32** that indicates which setup procedure to use. This value can be **NULL**. ### Return value Type: **HRESULT** If this function succeeds, it returns **S_OK**. Otherwise, it returns an **HRESULT** error code. ### Remarks This function may be implemented and exported by name by a DLL for use during application installation or setup. It is invoked by **regsvr32** to allow the DLL to perform tasks such as adding information to the registry. **DllInstall** is used only for application installation and setup. It should not be called by an application. It is similar in purpose to DllRegisterServer or DllUnregisterServer. Unlike these functions, **DllInstall** takes an input string which can be used to specify a variety of different actions. This allows a DLL to be installed in more than one way, based on any criteria that is appropriate. To use **DllInstall** with **regsvr32**, add a "/i" flag followed by a colon (:) and a string. The string will be passed to **DllInstall** as the _pszCmdLine_ parameter. If you omit the colon and string, _pszCmdLine_ will be set to **NULL**. The following example would be used to install a DLL. **regsvr32 /i:"Install_1" dllname.dll** **DllInstall** is invoked with _bInstall_ set to **TRUE** and _pszCmdLine_ set to "Install_1". To uninstall a DLL, use the following: **regsvr32 /u /i:"Install_1" dllname.dll** With both of the above examples, DllRegisterServer or DllUnregisterServer will also be called. To call **DllInstall** only, add a "/n" flag. **regsvr32 /n /i:"Install_1" dllname.dll** ### Requirements | Requirement | Value | | --- | --- | | **Minimum supported client** | Windows 2000 Professional, Windows XP [desktop apps only] | | **Minimum supported server** | Windows 2000 Server [desktop apps only] | | **Target Platform** | Windows | | **Header** | shlwapi.h | | **DLL** | Shlwapi.dll (version 4.71 or later) | ``` -------------------------------- ### PathIsRoot example in C++ Source: https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-pathisroota Example demonstrating the use of PathIsRoot with two path strings: one root path and one non-root path. The output shows the return values and the paths. ```cpp #include #include #include "Shlwapi.h" void main( void ) { // String path name 1. char buffer_1[ ] = "C:\\"; char *lpStr1; lpStr1 = buffer_1; // String path name 2. char buffer_2[ ] = "path\\file"; char *lpStr2; lpStr2 = buffer_2; // Variable to get the return from "PathIsRoot". int retval; // Test case with path not absolute. retval = PathIsRoot(lpStr1); cout << "The return from function is :" << retval << endl; cout << "The path does contain a root part :" << lpStr1 << endl; // Test case with path absolute. retval = PathIsRoot(lpStr2); cout << "The return from function is :" << retval << endl; cout << "The path does not contain part :" << lpStr2 << endl; } OUTPUT: ============ The return from function is :1 The path does contain a root part :C:\ The return from function is :0 The path does not contain part :path\file ============ ``` -------------------------------- ### Global Counter Usage Example Source: https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/ne-shlwapi-shglobalcounter A pseudocode example demonstrating how to use a global counter to verify whether Shell settings have changed. ```APIDOC ## Global Counter Usage Example ### Description Demonstrates how to use a global counter to check if Shell settings have changed. ### Code Example ``` void ValidateSomeSettings() { // Get the current GLOBALCOUNTER_SHELLSETTINGSCHANGED value. long lGlobalSettingsCounter = SHGlobalCounterGetValue(GLOBALCOUNTER_SHELLSETTINGSCHANGED); // Do some other work ... // Verify whether the Shell settings have changed since entering this method. if (lGlobalSettingsCounter == SHGlobalCounterGetValue(GLOBALCOUNTER_SHELLSETTINGSCHANGED)) { // Commit the work that was done earlier ... } else { // Shell settings have changed. Rollback and redo. ... } } ``` ``` -------------------------------- ### Example: Using PathRelativePathTo Source: https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-pathrelativepathtow A complete C++ example that includes the necessary headers, defines a main function, and calls PathRelativePathTo to compute a relative path. The output shows the expected result. ```cpp #include #include #include "Shlwapi.h" void main(void) { char szOut[MAX_PATH] = ""; char szFrom[ ] = "c:\\a\\b\\path"; char szTo[ ] = "c:\\a\\x\\y\\file"; cout << "The relative path is relative from: "; cout << szFrom; cout << "\n"; cout << "The relative path is relative to: "; cout << szTo; cout << "\n"; PathRelativePathTo(szOut, szFrom, FILE_ATTRIBUTE_DIRECTORY, szTo, FILE_ATTRIBUTE_NORMAL); cout << "The relative path is: "; cout << szOut; cout << "\n"; } OUTPUT: ================== The relative path is relative from: c:\a\b\path The relative path is relative to: c:\a\x\y\file The relative path is: ..\..\x\y\file ``` -------------------------------- ### Example: Implementing QueryInterface with QISearch Source: https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-qisearch This example shows how to use QISearch to implement QueryInterface for a class that supports IPersist and IPersistFolder. It uses the offsetofclass macro from ATL to compute interface offsets. Note that all base classes, including indirect ones like IPersist, must be included in the QITAB table. ```cpp class CSample : public IPersistFolder { public: CSample() { /* other construction goes here */ } STDMETHODIMP QueryInterface(REFIID riid, void **ppv); STDMETHODIMP_(ULONG) AddRef(); STDMETHODIMP_(ULONG) Release(); // *** IPersist *** STDMETHODIMP GetClassID(CLSID *pClassID); // *** IPersistFolder *** STDMETHODIMP Initialize(LPCITEMIDLIST pidl); private: // private members go here }; HRESULT CSample::QueryInterface(REFIID riid, void **ppv) { static QITAB rgqit[] = { QITABENT(CSample, IPersist), QITABENT(CSample, IPersistFolder) { 0 }, }; return QISearch(this, rgqit, IID_PPV_ARGS(&ppv)); } ``` -------------------------------- ### Example: Using PathGetArgs to extract arguments from paths Source: https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-pathgetargsw This example demonstrates how to use PathGetArgs on several path strings to extract the arguments. It includes the expected output showing the arguments found for each path. The function returns a pointer to the end of the string when no arguments are present. ```cpp #include #include #include "Shlwapi.h" void main( void ) { // Path_1 to search for file arguments (2 arguments): char buffer_1[ ] = "test.exe temp.txt sample.doc"; char *lpStr1; lpStr1 = buffer_1; // Path_2 to search for file arguments (3 arguments): char buffer_2[ ] = "test.exe 1 2 3"; char *lpStr2; lpStr2 = buffer_2; // Path_3 to search for file arguments (3 arguments): char buffer_3[ ] = "test.exe sample All 15"; char *lpStr3; lpStr3 = buffer_3; // Path_4 to search for file arguments (no arguments): char buffer_4[ ] = "test.exe"; char *lpStr4; lpStr4 = buffer_4; cout << "The path passed to the function was : " << lpStr1 << "\nThe arg(s)found in path 1 were : " << PathGetArgs(lpStr1) << endl; cout << "\nThe path passed to the function was : " << lpStr2 << "\nThe arg(s)found in path 2 were : " << PathGetArgs(lpStr2) << endl; cout << "\nThe path passed to the function was : " << lpStr3 << "\nThe arg(s)found in path 3 were : " << PathGetArgs(lpStr3) << endl; cout << "\nThe path passed to the function was : " << lpStr4 << "\nThe arg(s)found in path 4 were : " << PathGetArgs(lpStr4) << endl; } OUTPUT: =========== The path passed to the function was : test.exe temp.txt sample.doc The arg(s)found in path 1 were : temp.txt sample.doc The path passed to the function was : test.exe 1 2 3 The arg(s)found in path 2 were : 1 2 3 The path passed to the function was : test.exe sample All 15 The arg(s)found in path 3 were : sample All 15 The path passed to the function was : test.exe The arg(s)found in path 4 were : =========== ``` -------------------------------- ### Example: Using PathAddExtension to add file extensions Source: https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-pathaddextensiona This example demonstrates how to use PathAddExtension to add a file extension to a path string. It shows the behavior when the path already has an extension, when the path is a null string, and when the extension is provided. The output shows the modified path strings and return values. ```cpp #include #include #include "Shlwapi.h" void main( void ) { // String for path name without file name extension. char buffer_1[MAX_PATH] = "file"; char *lpStr1; lpStr1 = buffer_1; // String for path name with file name extension. char buffer_2[ ] = "file.doc"; char *lpStr2; lpStr2 = buffer_2; // String for extension name. char F_Ext[MAX_PATH] = ".txt"; char *lpStr3; lpStr3 = F_Ext; // Null string as path. char N_String[MAX_PATH] = "\0"; char *lpStr4; lpStr4 = N_String; // Path 1 without the file name extension. cout << "The original path string 1 is " << lpStr1 << endl; int ret_1 = PathAddExtension(lpStr1,lpStr3); cout << "The modified path string 1 is " << lpStr1 << endl; // Path 2 with the file name extension already there. cout << "The original path string 2 is " << lpStr2 << endl; int ret_2 = PathAddExtension(lpStr2,lpStr3); cout << "The modified path string 2 is " << lpStr2<< endl; // Path 3 null string as a path. int ret_3 = PathAddExtension(lpStr4,lpStr3); cout << "The return value is " << ret_3<< endl; cout << "The modified path on a null string is " << lpStr4<< endl; } OUTPUT: ----------------------- The original path string 1 is file The modified path string 1 is file.txt The original path string 2 is file.doc The modified path string 2 is file.doc The return value is 1 The modified path on a null string is .txt The return value is 1 ``` -------------------------------- ### C++ example using PathCanonicalizeA Source: https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-pathcanonicalizea This example demonstrates the PathCanonicalizeA function by canonicalizing several paths containing . and .. sequences. It shows the return value (TRUE) and the canonicalized path for each input. The example uses the ANSI version of the function, as indicated by the alias selection based on the UNICODE constant. ```cpp #include #include #include "Shlwapi.h" using namespace std; int main( void ) { // Path_1 destination buffer. char buffer_1[MAX_PATH] = "JustABufferToHoldTheCanonicalizedPathForAnExample"; char *lpStr1; lpStr1 = buffer_1; // Path_2 to be Canonicalized. char buffer_2[ ] = "A:\\name_1\\.\\name_2\\..\\name_3"; char *lpStr2; lpStr2 = buffer_2; // Path_3 to be Canonicalized. char buffer_3[ ] = "A:\\name_1\\..\\name_2\\.\\name_3"; char *lpStr3; lpStr3 = buffer_3; // Path_4 to be Canonicalized. char buffer_4[ ] = "A:\\name_1\\name_2\\.\\name_3\\..\\name_4"; char *lpStr4; lpStr4 = buffer_4; // Path_5 to be Canonicalized. char buffer_5[ ] = "A:\\name_1\\.\\name_2\\.\\name_3\\..\\name_4\\.."; char *lpStr5; lpStr5 = buffer_5; // Path_6 to be Canonicalized. char buffer_6[ ] = "C:\\.."; char *lpStr6; lpStr6 = buffer_6; cout << "The un-canonicalized path 2 is : " << lpStr2 << "\nThe return value is : " << PathCanonicalize(lpStr1,lpStr2) << "\nThe canonicalized path 1 is : " << lpStr1 << endl; cout << "\nThe un-canonicalized path 3 is : " << lpStr3 << "\nThe return value is : " << PathCanonicalize(lpStr1,lpStr3) << "\nThe canonicalized path 1 is : " << lpStr1 << endl; cout << "\nThe un-canonicalized path 4 is : " << lpStr4 << "\nThe return value is : " << PathCanonicalize(lpStr1,lpStr4) << "\nThe canonicalized path 1 is : " << lpStr1 << endl; cout << "\nThe un-canonicalized path 5 is : " << lpStr5 << "\nThe return value is : " << PathCanonicalize(lpStr1,lpStr5) << "\nThe canonicalized path 1 is : " << lpStr1 << endl; cout << "\nThe un-canonicalized path 6 is : " << lpStr6 << "\nThe return value is : " << PathCanonicalize(lpStr1,lpStr6) << "\nThe canonicalized path 1 is : " << lpStr1 << endl; } ``` ```text OUTPUT: --------- The un-canonicalized path 2 is : A:\name_1\.\name_2\..\name_3 The return value is : 1 The canonicalized path 1 is : A:\name_1\name_3 The un-canonicalized path 3 is : A:\name_1\..\name_2\.\name_3 The return value is : 1 The canonicalized path 1 is : A:\name_2\name_3 The un-canonicalized path 4 is : A:\name_1\name_2\.\name_3\..\name_4 The return value is : 1 The canonicalized path 1 is : A:\name_1\name_2\name_4 The un-canonicalized path 5 is : A:\name_1\.\name_2\.\name_3\..\name_4\.. The return value is : 1 The canonicalized path 1 is : A:\name_1\name_2 The un-canonicalized path 6 is : C:\.. The return value is : 1 The canonicalized path 1 is : C:\ ``` -------------------------------- ### PathIsURL example: test URL strings Source: https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-pathisurlw This example tests three strings with PathIsURL and prints the results. It uses the ANSI version of the function (PathIsURL) and includes the expected output. The function returns TRUE for valid URL formats and FALSE otherwise. ```cpp #include #include #include "Shlwapi.h" void main( void ) { // String path name 1. char buffer_1[ ] = "http://www.microsoft.com/software/index.html"; char *lpStr1; lpStr1 = buffer_1; // String path name 2. char buffer_2[ ] = "http://www.microsoft.com"; char *lpStr2; lpStr2 = buffer_2; // String path name 3. char buffer_3[ ] = "microsoft.com"; char *lpStr3; lpStr3 = buffer_3; // Variable to get the return // from "PathIsURL". int retval; // Test path name 1. retval = PathIsURL(lpStr1); cout << "The contents of String 1: " << lpStr1 << "\nThe return value from the function is " << retval << " = TRUE" << endl; // Test path name 2. retval = PathIsURL(lpStr2); cout << "The contents of String 2: " << lpStr2 << "\nThe return value from the function is " << retval << " = TRUE" << endl; // Test path name 3. retval = PathIsURL(lpStr3); cout << "The contents of String 3: " << lpStr3 << "\nThe return value from the function is " << retval << " = FALSE"<< endl; } OUTPUT: ============= The contents of String 1: http://www.microsoft.com/software/index.html The return value from the function is 1 = TRUE The contents of String 2: http://www.microsoft.com The return value from the function is 1 = TRUE The contents of String 3: microsoft.com The return value from the function is 0 = FALSE ``` -------------------------------- ### PathRemoveArgs example with output Source: https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-pathremoveargsa This example shows how to use PathRemoveArgs to remove arguments from a path. It includes the required headers, a main function that initializes a path with arguments, calls PathRemoveArgs, and prints the path before and after. The output shows the path with arguments removed. ```cpp #include #include #include "Shlwapi.h" void main( void ) { // Path with arguments. char buffer_1[ ] = "c:\\a\\b\\FileA Arg1 Arg2"; char *lpStr1; lpStr1 = buffer_1; // Path before "PathRemoveArgs". cout << "Path before calling \"PathRemoveArgs\": " << lpStr1 << endl; // Call function "PathRemoveArgs". PathRemoveArgs(lpStr1); // Path after "PathRemoveArgs". cout << "Path after calling \"PathRemoveArgs\": " << lpStr1 << endl; } OUTPUT: ================== Path before calling "PathRemoveArgs": c:\a\b\FileA Arg1 Arg2 Path after calling "PathRemoveArgs": c:\a\b\FileA ``` -------------------------------- ### PathMakePretty example usage Source: https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-pathmakeprettya Example demonstrating the use of PathMakePretty with two paths: one all-uppercase and one mixed-case. The output shows that the uppercase path is converted to lowercase and returns TRUE, while the mixed-case path is unchanged and returns FALSE. ```cpp #include #include #include "Shlwapi.h" void main( void ) { // Path name 1. char buffer_1[ ] = "C:\\TEST\\FILE"; char *lpStr1; lpStr1 = buffer_1; // Path name 2. char buffer_2[ ] = "c:\\test\\file"; char *lpStr2; lpStr2 = buffer_2; // Test path name 1. cout << "The content of the unconverted path is : " << lpStr1 << endl; cout << "The \"PathMakePretty\" function returns the value " << PathMakePretty(lpStr1) << " = TRUE & converts" << endl; cout << "The content of the converted path is : " << lpStr1 << endl; // Test path name 2. cout << "\nThe content of the unconverted path is : " << lpStr2 << endl; cout << "The \"PathMakePretty\" function returns the value " << PathMakePretty(lpStr2) << " = FALSE & no conversion" << endl; cout << "The content of the converted path is : " << lpStr2 << endl; } OUTPUT: ============= The content of the unconverted path is : C:\TEST\FILE The "PathMakePretty" function returns the value 1 = TRUE & converts The content of the converted path is : C:\test\file The content of the unconverted path is : c:\test\file The "PathMakePretty" function returns the value 0 = FALSE & no conversion The content of the converted path is : c:\test\file ``` -------------------------------- ### Example usage of StrFromTimeInterval Source: https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-strfromtimeintervalw This example demonstrates calling StrFromTimeInterval with various time intervals and digit counts, printing the return value and the resulting buffer contents. The output shows the formatted strings and the number of characters returned. ```cpp #include #include #include "Shlwapi.h" void main(void) { char TimeString[256]; char *pszOut; pszOut = TimeString; cout << "The return value from the call to" << "\nthe function StrFromTimeInterval will" << "\nreturn the number of elements in the buffer: " << endl; cout << "\nThe return from StrFromTimeInterval is " << StrFromTimeInterval(pszOut,30, 34000,30); cout << "\nThe contents of the TimeString Buffer " << pszOut << endl; cout << "The return from StrFromTimeInterval is " << StrFromTimeInterval(pszOut,30, 74000,3); cout << "\nThe contents of the TimeString Buffer " << pszOut << endl; cout << "The return from StrFromTimeInterval is " << StrFromTimeInterval(pszOut,30, 74000,2); cout << "\nThe contents of the TimeString Buffer " << pszOut << endl; cout << "The return from StrFromTimeInterval is " << StrFromTimeInterval(pszOut,30, 74000,1) << "\nThe contents of the TimeString Buffer " << pszOut << endl; } OUTPUT: - - - - - The return value from the call to the function StrFromTimeInterval will return the number of elements in the buffer: The return from StrFromTimeInterval is 7 The contents of the TimeString Buffer 34 sec The return from StrFromTimeInterval is 13 The contents of the TimeString Buffer 1 min 14 sec The return from StrFromTimeInterval is 13 The contents of the TimeString Buffer 1 min 10 sec The return from StrFromTimeInterval is 6 The contents of the TimeString Buffer 1 min ``` -------------------------------- ### C++ example using PathCombine to combine directory and file paths Source: https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-pathcombinew This example demonstrates how to use the PathCombine function to concatenate a directory path and a file path. It includes the necessary headers, declares buffers for the combined path and the input strings, and prints the resulting combined path. The output shows the expected result: 'C:\One\Two\Three'. ```cpp #include #include #include "Shlwapi.h" int main( void ) { // Buffer to hold combined path. char buffer_1[MAX_PATH] = ""; char *lpStr1; lpStr1 = buffer_1; // String for balance of path name. char buffer_2[ ] = "One\\Two\\Three"; char *lpStr2; lpStr2 = buffer_2; // String for directory name. char buffer_3[ ] = "C:"; char *lpStr3; lpStr3 = buffer_3; cout << "The file path to be combined is " << lpStr2 << endl; cout << "The directory name path is " << lpStr3 << endl; cout << "The combined path is " << PathCombine(lpStr1,lpStr3,lpStr2) << endl; } ``` -------------------------------- ### Example: Using UrlFixupW to correct URLs Source: https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-urlfixupw This example defines a sample function that calls UrlFixupW on various URL strings and prints the corrected URL or 'failed' if the URL cannot be recognized. The main function tests several inputs, including some that demonstrate the heuristic's limitations. The output shows the corrected URLs for the successful cases and 'failed' for the ones that could not be corrected. ```cpp #include #include #include #include void sample(LPCWSTR pszUrl) { WCHAR szBuf[256]; HRESULT hr = UrlFixupW(pszUrl, szBuf, 256); if (hr == S_OK) { wprintf(L"%-35s %s\n", pszUrl, szBuf); } else { wprintf(L"%-35s failed\n", pszUrl); } } int __cdecl main() { sample(L"http://www.microsoft.com"); sample(L"mail:someone@example.com"); sample(L"abc:def"); sample(L"someone@example.com"); sample(L"htpp:wwwmicrosoft.com"); sample(L"htps:\\\\www.microsoft.com"); sample(L"http:someone@example.com"); return 0; } ``` ```text http://www.microsoft.com http://www.microsoft.com http:www.microsoft.com http://www.microsoft.com mail:someone@example.com mailto:someone@example.com abc:def failed someone@example.com failed htpp:wwwmicrosoft.com http://wwwmicrosoft.com htps:\\www.microsoft.com http://www.microsoft.com http:someone@example.com http://someone@example.com ``` -------------------------------- ### Example: Parsing a path and icon index with PathParseIconLocation Source: https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-pathparseiconlocationw This example shows how to use PathParseIconLocation to parse a string containing a file path and an icon index. It defines a buffer with the input string, calls the function, and prints the resulting path and icon index. The output shows the path without the icon index and the returned icon index value. ```cpp #include #include #include "Shlwapi.h" void main(void) { // Path to parse for file and icon index. char buffer_1[ ] = "C:\\TEST\\sample.txt,3"; char *lpStr1; lpStr1 = buffer_1; // Return value from "PathParseIconLocation". int retval; // Search a path to parse for file and icon index. retval = PathParseIconLocation(lpStr1); cout << "The path to parse for file and icon index is : " << lpStr1 << endl; cout << "PathParseIconLocation returns the icon index of: " << retval << endl; } OUTPUT: ========== The path to parse for file and icon index is : C:\TEST\sample.txt PathParseIconLocation returns the icon index of: 3 ``` -------------------------------- ### PathFileExists example: checking file existence Source: https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-pathfileexistsw This example demonstrates how to use the PathFileExists function to check if a file exists. It defines two file paths, one valid and one invalid, and calls PathFileExists on each, printing the results. The output shows the return values: 1 for the existing file and 0 for the non-existing file. ```cpp #include #include #include "Shlwapi.h" void main(void) { // Valid file path name (file is there). char buffer_1[ ] = "C:\\TEST\\file.txt"; char *lpStr1; lpStr1 = buffer_1; // Invalid file path name (file is not there). char buffer_2[ ] = "C:\\TEST\\file.doc"; char *lpStr2; lpStr2 = buffer_2; // Return value from "PathFileExists". int retval; // Search for the presence of a file with a true result. retval = PathFileExists(lpStr1); if(retval == 1) { cout << "Search for the file path of : " << lpStr1 << endl; cout << "The file requested \"" << lpStr1 << "\" is a valid file" << endl; cout << "The return from function is : " << retval << endl; } else { cout << "\nThe file requested " << lpStr1 << " is not a valid file" << endl; cout << "The return from function is : " << retval << endl; } // Search for the presence of a file with a false result. retval = PathFileExists(lpStr2); if(retval == 1) { cout << "\nThe file requested " << lpStr2 << "is a valid file" << endl; cout << "Search for the file path of : " << lpStr2 << endl; cout << "The return from function is : " << retval << endl; } else { cout << "\nThe file requested \"" << lpStr2 << "\" is not a valid file" << endl; cout << "The return from function is : " << retval << endl; } } OUTPUT ============== Search for the file path of : C:\TEST\file.txt The file requested "C:\TEST\file.txt" is a valid file The return from function is : 1 The file requested "C:\TEST\file.doc" is not a valid file The return from function is : 0 ``` -------------------------------- ### C++ example demonstrating PathCanonicalize with various paths Source: https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-pathcanonicalizew This C++ example initializes several paths and calls PathCanonicalize on each, printing the original path, the return value, and the canonicalized path. It demonstrates the behavior of the function with different combinations of '.' and '..' sequences, including a case where the root is reached. The output shows the canonicalized paths and return values. ```cpp #include #include #include "Shlwapi.h" using namespace std; int main( void ) { // Path_1 destination buffer. char buffer_1[MAX_PATH] = "JustABufferToHoldTheCanonicalizedPathForAnExample"; char *lpStr1; lpStr1 = buffer_1; // Path_2 to be Canonicalized. char buffer_2[ ] = "A:\\name_1\\.\\name_2\\..\\name_3"; char *lpStr2; lpStr2 = buffer_2; // Path_3 to be Canonicalized. char buffer_3[ ] = "A:\\name_1\\..\\name_2\\.\\name_3"; char *lpStr3; lpStr3 = buffer_3; // Path_4 to be Canonicalized. char buffer_4[ ] = "A:\\name_1\\name_2\\.\\name_3\\..\\name_4"; char *lpStr4; lpStr4 = buffer_4; // Path_5 to be Canonicalized. char buffer_5[ ] = "A:\\name_1\\.\\name_2\\.\\name_3\\..\\name_4\\.."; char *lpStr5; lpStr5 = buffer_5; // Path_6 to be Canonicalized. char buffer_6[ ] = "C:\\.."; char *lpStr6; lpStr6 = buffer_6; cout << "The un-canonicalized path 2 is : " << lpStr2 << "\nThe return value is : " << PathCanonicalize(lpStr1,lpStr2) << "\nThe canonicalized path 1 is : " << lpStr1 << endl; cout << "\nThe un-canonicalized path 3 is : " << lpStr3 << "\nThe return value is : " << PathCanonicalize(lpStr1,lpStr3) << "\nThe canonicalized path 1 is : " << lpStr1 << endl; cout << "\nThe un-canonicalized path 4 is : " << lpStr4 << "\nThe return value is : " << PathCanonicalize(lpStr1,lpStr4) << "\nThe canonicalized path 1 is : " << lpStr1 << endl; cout << "\nThe un-canonicalized path 5 is : " << lpStr5 << "\nThe return value is : " << PathCanonicalize(lpStr1,lpStr5) << "\nThe canonicalized path 1 is : " << lpStr1 << endl; cout << "\nThe un-canonicalized path 6 is : " << lpStr6 << "\nThe return value is : " << PathCanonicalize(lpStr1,lpStr6) << "\nThe canonicalized path 1 is : " << lpStr1 << endl; } ``` ```text OUTPUT: --------- The un-canonicalized path 2 is : A:\name_1\.\name_2\..\name_3 The return value is : 1 The canonicalized path 1 is : A:\name_1\name_3 The un-canonicalized path 3 is : A:\name_1\..\name_2\.\name_3 The return value is : 1 The canonicalized path 1 is : A:\name_2\name_3 The un-canonicalized path 4 is : A:\name_1\name_2\.\name_3\..\name_4 The return value is : 1 The canonicalized path 1 is : A:\name_1\name_2\name_4 The un-canonicalized path 5 is : A:\name_1\.\name_2\.\name_3\..\name_4\.. The return value is : 1 The canonicalized path 1 is : A:\name_1\name_2 The un-canonicalized path 6 is : C:\.. The return value is : 1 The canonicalized path 1 is : C:\ ``` -------------------------------- ### Example: Using IUnknown_Set to manage COM interface pointers Source: https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-iunknown_set Shows how to use IUnknown_Set to assign a new interface pointer, releasing the previous one. The example creates two streams, assigns them with IUnknown_Set, and releases them. It also calls IUnknown_AtomcRelease to release the final pointer. ```cpp void sample() { IUnknown *punk = NULL; IStream* pstm = NULL; if (SUCCEEDED(CreateStreamOnHGlobal(NULL, TRUE, &pstm)) { // since punk == NULL, this merely copies the value and AddRef()s it IUnknown_Set(&punk, pstm); pstm->Release(); if (SUCCEEDED(CreateStreamOnHGlobal(NULL, TRUE, &pstm)) { // this call will release the old value of punk before copying the // new value and AddRef()ing it IUnknown_Set(&punk, pstm); pstm->Release(); } } // This call will release whatever punk points to, if anything. IUnknown_AtomcRelease((void**)&punk); // at this point, punk == NULL } ``` -------------------------------- ### PathCompactPathA usage example with output Source: https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-pathcompactpatha This example demonstrates the PathCompactPath function (ANSI version) by truncating the same path at different pixel widths (125, 120, 110, 25) and printing the results. It requires including windows.h, iostream.h, and Shlwapi.h, and uses a display DC handle for font metrics. The output shows how the path is progressively compacted with ellipses. ```cpp #include #include #include "Shlwapi.h" HDC hdc; /* display DC handle to current font metrics */ void main( void ) { // String path name 1. char buffer_1[MAX_PATH] = "C:\\path1\\path2\\sample.txt"; char *lpStr1; lpStr1 = buffer_1; // String path name 2. char buffer_2[MAX_PATH] = "C:\\path1\\path2\\sample.txt"; char *lpStr2; lpStr2 = buffer_2; // String path name 3. char buffer_3[MAX_PATH] = "C:\\path1\\path2\\sample.txt"; char *lpStr3; lpStr3 = buffer_3; // String path name 4. char buffer_4[MAX_PATH] = "C:\\path1\\path2\\sample.txt"; char *lpStr4; lpStr4 = buffer_4; // Variable to get the return from "PathCompactPath". int retval; cout << "The un-truncated path is " << lpStr1 << endl; retval = PathCompactPath(hdc,lpStr1,125); cout << "The truncated path at 125 pixels is : " << lpStr1 << endl; retval = PathCompactPath(hdc,lpStr2,120); cout << "The truncated path at 120 pixels is : " << lpStr2 << endl; retval = PathCompactPath(hdc,lpStr3,110); cout << "The truncated path at 110 pixels is : " << lpStr3 << endl; retval = PathCompactPath(hdc,lpStr4,25); cout << "The truncated path at 25 pixels is : " << lpStr4 << endl; } OUTPUT: =========== The un-truncated path is C:\path1\path2\sample.txt The truncated path at 125 pixels is : C:\path1\...\sample.txt The truncated path at 120 pixels is : C:\pat...\sample.txt The truncated path at 110 pixels is : C:\p...\sample.txt The truncated path at 25 pixels is : ...\sample.txt ``` -------------------------------- ### Example: Releasing an IStream with IUnknown_AtomicRelease Source: https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-iunknown_atomicrelease Shows how to release an IStream pointer if it exists. The function sets the pointer to NULL after releasing it. ```cpp void sample() { IStream *pstm = NULL; CreateStreamOnHGlobal(NULL, TRUE, &pstm); IUnknown_AtomicRelease((void**)&pstm); // At this point, pstm is NULL } ``` -------------------------------- ### Console application demonstrating PathFindNextComponent Source: https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-pathfindnextcomponentw This example shows how to use PathFindNextComponent in a console application. It walks a full path by repeatedly calling the function and also demonstrates results for various path forms. To run this code in Visual Studio, link to Shlwapi.lib and define UNICODE in the preprocessor commands. ```cpp #include #include #include #pragma comment(lib, "shlwapi.lib") // Link to this file. int main() { using namespace std; PCWSTR path = L"c:\\path1\\path2\\file.txt"; // This loop passes a full path to PathFindNextComponent and feeds the // results of that call back into the function until the entire path has // been walked. while (path) { PCWSTR oldPath = path; path = PathFindNextComponent(path); // The path variable pointed to the terminating null character. if (path == NULL) { wcout << L"The terminating null character returns NULL\n\n"; } // The path variable pointed to a path with only one component. else if (*path == 0) { wcout << L"The path " << oldPath << L" returns a pointer to the terminating null character\n"; } else { wcout << L"The path " << oldPath << L" returns " << path << L"\n"; } } // These calls demonstrate the results of different path forms. // Note that where those paths begin with backslashes, those // backslashes are merely stripped away and the entire path is returned. PCWSTR path1 = L"\\path1"; wcout << L"The path " << path1 << L" returns " << PathFindNextComponent(path1); PCWSTR path2 = L"\\path1\\path2"; wcout << L"\nThe path " << path2 << L" returns " << PathFindNextComponent(path2); PCWSTR path3 = L"path1\\path2"; wcout << L"\nThe path " << path3 << L" returns " << PathFindNextComponent(path3); wcout << L"\nThe path " << L"c:\\file.txt" << L" returns " << PathFindNextComponent(L"c:\\file.txt"); return 0; } OUTPUT: =========== The path c:\path1\path2\file.txt returns path1\path2\file.txt The path path1\path2\file.txt returns path2\file.txt The path path2\file.txt returns file.txt The path file.txt returns a pointer to the terminating null character The terminating null character returns NULL The path \path1 returns path1 The path \path1\path2 returns path1\path2 The path path1\path2 returns path2 The path c:\file.txt returns file.txt ``` -------------------------------- ### SHMessageBoxCheck example call Source: https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-shmessageboxcheckw Example call to SHMessageBoxCheck with a warning message, MB_YESNO flag, IDNO default, and a GUID to identify the dialog for suppression. Note that if the user suppresses the dialog, subsequent calls return the iDefault value (IDNO), not the user's original choice. ```cpp int iResult = SHMessageBoxCheck(hwnd, TEXT("Do you want to exit without saving?"), TEXT("Warning"), MB_YESNO, IDNO, TEXT("{d9108ba3-9a61-4398-bfbc-b02102c77e8a}"); ```