include/vcl/vclenum.hxx       |   14 +++++++++++
 include/vcl/window.hxx        |    3 ++
 vcl/inc/salframe.hxx          |    3 ++
 vcl/inc/win/salframe.h        |    5 +++
 vcl/source/window/layout.cxx  |    3 ++
 vcl/source/window/window3.cxx |   16 ++++++++++++
 vcl/win/window/salframe.cxx   |   53 ++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 97 insertions(+)

New commits:
commit 0c6642ed3a2dbcd54456f61706606fa3371b70ba
Author:     Vasily Melenchuk <[email protected]>
AuthorDate: Sat Apr 27 14:23:12 2024 +0200
Commit:     Thorsten Behrens <[email protected]>
CommitDate: Wed Jul 17 21:05:15 2024 +0200

    vcl: support for Windows ITaskbarList3 interface
    
    And a demo implementation for these features as a taskbar window
    will become red once LO is displaying any error message.
    
    Change-Id: Ifc04026c699059da2e457de2c69e7363e756109c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166740
    Tested-by: Jenkins
    Reviewed-by: Thorsten Behrens <[email protected]>

diff --git a/include/vcl/vclenum.hxx b/include/vcl/vclenum.hxx
index c8f27fb9da52..f1938105a996 100644
--- a/include/vcl/vclenum.hxx
+++ b/include/vcl/vclenum.hxx
@@ -196,6 +196,20 @@ enum class VclPackType
     LAST = End
 };
 
+enum class VclTaskBarStates {
+    // Default, no specifics
+    Normal,
+    // Display some progress defined by SetTaskBarProgress
+    Progress,
+    // Something going on, but no exact progress scale
+    ProgressUnknown,
+    // Process on pause
+    Paused,
+    // Some error did happen
+    Error
+};
+
+
 // Return Values from Dialog::Execute
 //!!! in case of changes adjust /basic/source/runtime/methods.cxx msgbox
 
diff --git a/include/vcl/window.hxx b/include/vcl/window.hxx
index c78c214a5b60..95aba300f41e 100644
--- a/include/vcl/window.hxx
+++ b/include/vcl/window.hxx
@@ -1122,6 +1122,9 @@ public:
     /// Use OS specific way to bring user attention to current window
     virtual void FlashWindow() const;
 
+    virtual void SetTaskBarProgress(int nCurrentProgress);
+    virtual void SetTaskBarState(VclTaskBarStates eTaskBarState);
+
     /** @name Accessibility
      */
     ///@{
diff --git a/vcl/inc/salframe.hxx b/vcl/inc/salframe.hxx
index bce015ee4f73..ab2ce4d0430f 100644
--- a/vcl/inc/salframe.hxx
+++ b/vcl/inc/salframe.hxx
@@ -316,6 +316,9 @@ public:
     // in nOffset, nChars.
     static Selection        CalcDeleteSurroundingSelection(std::u16string_view 
rSurroundingText,
                                                            sal_Int32 
nCursorIndex, int nOffset, int nChars);
+
+    virtual void  SetTaskBarProgress(int /*nCurrentProgress*/) {}
+    virtual void  SetTaskBarState(VclTaskBarStates /*eTaskBarState*/) {}
 };
 
 #ifdef _WIN32
diff --git a/vcl/inc/win/salframe.h b/vcl/inc/win/salframe.h
index b9ddea89476a..e2f41822be0a 100644
--- a/vcl/inc/win/salframe.h
+++ b/vcl/inc/win/salframe.h
@@ -29,10 +29,12 @@
 #include <svsys.h>
 
 class WinSalGraphics;
+struct ITaskbarList3;
 
 class WinSalFrame final: public SalFrame
 {
     vcl::WindowState m_eState;
+    ITaskbarList3* m_pTaskbarList3;
 
 public:
     HWND                    mhWnd;                  // Window handle
@@ -146,6 +148,9 @@ public:
     constexpr vcl::WindowState state() const { return m_eState; }
     void UpdateFrameState();
     constexpr bool isFullScreen() const { return bool(m_eState & 
vcl::WindowState::FullScreen); }
+
+    virtual void  SetTaskBarProgress(int nCurrentProgress) override;
+    virtual void  SetTaskBarState(VclTaskBarStates eTaskBarState) override;
 };
 
 void ImplSalGetWorkArea( HWND hWnd, RECT *pRect, const RECT *pParentRect );
diff --git a/vcl/source/window/layout.cxx b/vcl/source/window/layout.cxx
index 2d42d305498e..14c7c9ade823 100644
--- a/vcl/source/window/layout.cxx
+++ b/vcl/source/window/layout.cxx
@@ -2563,6 +2563,7 @@ MessageDialog::MessageDialog(vcl::Window* pParent,
             break;
         case VclMessageType::Error:
             SetText(GetStandardErrorBoxText());
+            SetTaskBarState(VclTaskBarStates::Error);
             break;
         case VclMessageType::Other:
             SetText(Application::GetDisplayName());
@@ -2572,6 +2573,8 @@ MessageDialog::MessageDialog(vcl::Window* pParent,
 
 void MessageDialog::dispose()
 {
+    SetTaskBarState(VclTaskBarStates::Normal);
+
     disposeOwnedButtons();
     m_pPrimaryMessage.disposeAndClear();
     m_pSecondaryMessage.disposeAndClear();
diff --git a/vcl/source/window/window3.cxx b/vcl/source/window/window3.cxx
index 002c892f592c..ce1f3ff9030c 100644
--- a/vcl/source/window/window3.cxx
+++ b/vcl/source/window/window3.cxx
@@ -224,6 +224,22 @@ void Window::FlashWindow() const
         pMyParent->mpWindowImpl->mpFrame->FlashWindow();
 }
 
+void Window::SetTaskBarProgress(int nCurrentProgress)
+{
+    vcl::Window* pMyParent = ImplGetTopmostFrameWindow();
+
+    if (pMyParent && pMyParent->mpWindowImpl)
+        pMyParent->mpWindowImpl->mpFrame->SetTaskBarProgress(nCurrentProgress);
+}
+
+void Window::SetTaskBarState(VclTaskBarStates eTaskBarState)
+{
+    vcl::Window* pMyParent = ImplGetTopmostFrameWindow();
+
+    if (pMyParent && pMyParent->mpWindowImpl)
+        pMyParent->mpWindowImpl->mpFrame->SetTaskBarState(eTaskBarState);
+}
+
 } /* namespace vcl */
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/win/window/salframe.cxx b/vcl/win/window/salframe.cxx
index 1661d3408fa8..1cf551c00d78 100644
--- a/vcl/win/window/salframe.cxx
+++ b/vcl/win/window/salframe.cxx
@@ -903,6 +903,7 @@ WinSalFrame::WinSalFrame()
     mpNextClipRect      = nullptr;
     mnDisplay           = 0;
     mbPropertiesStored  = false;
+    m_pTaskbarList3     = nullptr;
 
     // get data, when making 1st frame
     if ( !pSalData->mpFirstFrame )
@@ -985,6 +986,11 @@ WinSalFrame::~WinSalFrame()
         mpLocalGraphics = nullptr;
     }
 
+    if ( m_pTaskbarList3 )
+    {
+        m_pTaskbarList3->Release();
+    }
+
     if ( mhWnd )
     {
         // reset mouse leave data
@@ -3159,6 +3165,53 @@ bool WinSalFrame::GetUseReducedAnimation() const
     return !bEnableAnimation;
 }
 
+void WinSalFrame::SetTaskBarProgress(int nCurrentProgress)
+{
+    if (!m_pTaskbarList3)
+    {
+        HRESULT hr = CoCreateInstance(CLSID_TaskbarList, NULL, 
CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (void **)&m_pTaskbarList3);
+        if (!SUCCEEDED(hr) || !m_pTaskbarList3)
+            return;
+    }
+
+    m_pTaskbarList3->SetProgressValue(mhWnd, nCurrentProgress, 100);
+}
+
+void WinSalFrame::SetTaskBarState(VclTaskBarStates eTaskBarState)
+{
+    if (!m_pTaskbarList3)
+    {
+        HRESULT hr = CoCreateInstance(CLSID_TaskbarList, NULL, 
CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (void **)&m_pTaskbarList3);
+        if (!SUCCEEDED(hr) || !m_pTaskbarList3)
+            return;
+    }
+
+    TBPFLAG nFlag;
+    switch (eTaskBarState)
+    {
+        case VclTaskBarStates::Progress:
+            nFlag = TBPF_NORMAL;
+            break;
+        case VclTaskBarStates::ProgressUnknown:
+            nFlag = TBPF_INDETERMINATE;
+            break;
+        case VclTaskBarStates::Paused:
+            nFlag = TBPF_PAUSED;
+            SetTaskBarProgress(100);
+            break;
+        case VclTaskBarStates::Error:
+            nFlag = TBPF_ERROR;
+            SetTaskBarProgress(100);
+            break;
+        case VclTaskBarStates::Normal:
+        default:
+            nFlag = TBPF_NOPROGRESS;
+            break;
+    }
+
+    m_pTaskbarList3->SetProgressState(mhWnd, nFlag);
+}
+
 static bool ImplHandleMouseMsg( HWND hWnd, UINT nMsg,
                                 WPARAM wParam, LPARAM lParam )
 {

Reply via email to