Advertisement
alaestor

Example of IDesktopWallpaper::AdvanceSlideshow

Nov 23rd, 2022
856
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.73 KB | Source Code | 0 0
  1. #include <stdexcept> // runtime_error
  2. #include <memory> // unique_ptr
  3.  
  4. #define WIN32_LEAN_AND_MEAN
  5. #include <windows.h>
  6. #include <initguid.h> // CLSID_DesktopWallpaper, IID_IDesktopWallpaper
  7. #include <shlobj.h> // COM nonsense
  8.  
  9. /*
  10.     This requires linking against ole32 (pass `-lole32` if using GCC)
  11.  
  12.     THIS WAS WRITTEN QUICK AND DIRTY!!
  13.  
  14.     I tried to keep this example simple, but also not abandon best practices.
  15.  
  16.     The error checks only tell you that things blew up. You shoud log the
  17.     error code along with other useful information (std::source_location, etc)
  18.     so can also find out _why_ it blew up.
  19.  
  20.     I'm using a struct and a unique_ptr to automate lifetime management &
  21.     clean-up of the COM resources (RAII). If you were writing this as part
  22.     of a public API / library, you'd probably want to provide a more safe and
  23.     stable interface which would require a more well-designed COM abstraction.
  24. */
  25.  
  26. struct raii_com
  27. {
  28.     [[nodiscard]] explicit raii_com(
  29.         const tagCOINIT tag = COINIT_APARTMENTTHREADED)
  30.     {
  31.         if (CoInitializeEx(NULL, tag) != S_OK) throw std::runtime_error(
  32.             "A raii_com instance failed to initialize :(");
  33.     }
  34.  
  35.     ~raii_com() noexcept
  36.     { CoUninitialize(); }
  37. };
  38.  
  39. /*
  40.     This is a type alias for a unique_ptr that will hold our IDesktopWallpaper
  41.     resource, and a pointer to a custom deleter function. When the unique_ptr
  42.     is destroyed, it will pass the IDesktopWallpaper* to the deleter function
  43.     which will handle clean-up. Not perfect, but better than a raw pointer.
  44. */
  45. using raii_desktop_wallpaper =
  46.     std::unique_ptr<IDesktopWallpaper, void(*)(IDesktopWallpaper*)>;
  47.  
  48. // The `raii_com` argument just helps guarantee that one exists
  49. raii_desktop_wallpaper desktop_wallpaper_factory(const raii_com&)
  50. {
  51.     // Create an instance of the wallpaper thingy
  52.     IDesktopWallpaper* our_new_resource;
  53.     if (CoCreateInstance(
  54.             CLSID_DesktopWallpaper,
  55.             NULL,
  56.             CLSCTX_LOCAL_SERVER,
  57.             IID_IDesktopWallpaper,
  58.             reinterpret_cast<void**>(&our_new_resource))
  59.         != S_OK)
  60.             throw std::runtime_error(
  61.                 "desktop_wallpaper_factory() failed :(");
  62.  
  63.     // Define the clean-up function (Lambda here, but could be normal func).
  64.     const auto our_custom_deleter{
  65.         [](IDesktopWallpaper* const p) noexcept
  66.         {
  67.             if (p != nullptr)
  68.                 p->Release();
  69.         }
  70.     };
  71.  
  72.     // Implicitly construct and return a `raii_desktop_wallpaper`
  73.     return {our_new_resource, our_custom_deleter};
  74. }
  75.  
  76. int main()
  77. {
  78.     const raii_com com;
  79.     const auto wallpaper{ desktop_wallpaper_factory(com) };
  80.  
  81.     if (wallpaper->AdvanceSlideshow(NULL, DSD_FORWARD) != S_OK)
  82.         throw std::runtime_error("AdvanceSlideshow failed :(");
  83.  
  84.     // No need to call wallpaper->Release() or CoUninitialize() because
  85.     // clean-up is managed by the wrapper object lifetimes
  86.  
  87.     return 0;
  88. }
  89.  
Tags: win32 Com
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement