Ángel González wrote:

I have adapted the above patch to C. See attachment.

What compiler did you use? I failed to compile your version
using MSVC v19.

Warning: I haven't tested it other than verifying that it compiles.

I've modified tbprogress.c to compile with both C and C++ using
MSVC v19. TDM-gcc 5.1 remains to be tested. The old-school MingW
(mingw.org) doesn't seems to have an up-to-date <shobjidl.h>. So
I've given up on that. tbprogress.c is attached. It seems to work
fine.

Contrary to the Windows Console title progress in background-mode,
the ITaskbarList3 works fine (as it's not related to the connhost
in any way). The "title progress" stops AFAICS, since 'FreeConsole()'
is called in ws_hangup().

--
--gv

/*
 * Adapted from:
 *   https://eternallybored.org/misc/wget/src/taskbar-progress.patch
 */

#if !defined(__cplusplus)
  #define CINTERFACE
  #define COBJMACROS
#endif

#include "config.h"

#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0500
#endif

#include <windows.h>
#include <commctrl.h>
#include <objbase.h>
#include <shobjidl.h>

#include "tbprogress.h"

#if !defined(_SHLOBJIDL_H) && !defined(__ITaskbarList3_INTERFACE_DEFINED__)
#error This file is not for you. Set ENABLE_TASKBAR=0.
#endif

const GUID CLSID_TaskbarList = { 0x56FDF344, 0xFD6D, 0x11d0, { 
0x95,0x8A,0x00,0x60,0x97,0xC9,0xA0,0x90 } };
const GUID IID_ITaskbarList1 = { 0x56FDF342, 0xFD6D, 0x11d0, { 
0x95,0x8A,0x00,0x60,0x97,0xC9,0xA0,0x90 } };
const GUID IID_ITaskbarList3 = { 0xea1afb91, 0x9e28, 0x4b86, { 
0x90,0xe9,0x9e,0x9f,0x8a,0x5e,0xef,0xaf } };

#if !defined(__ITaskbarList3_INTERFACE_DEFINED__)
  typedef enum {
    TBPF_NOPROGRESS    = 0, /* Normal state / no progress bar */
    TBPF_INDETERMINATE = 1, /* Marquee style progress bar */
    TBPF_NORMAL        = 2, /* Standard progress bar */
    TBPF_ERROR         = 4, /* Red taskbar button to indicate an error occurred 
*/
    TBPF_PAUSED        = 8  /* Yellow taskbar button to indicate user attention 
*/
  } TBPFLAG;

  typedef void* LPTHUMBBUTTON;  /* dummy typedef! */
  typedef enum { TBATF_DUMMY } TBATFLAG;

  #undef  INTERFACE
  #define INTERFACE ITaskbarList3
  DECLARE_INTERFACE_(ITaskbarList3,IUnknown)
  {
    STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;
    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
    STDMETHOD_(ULONG,Release)(THIS) PURE;

    /* ITaskbarList(1) */
    STDMETHOD(HrInit)(THIS) PURE;
    STDMETHOD(AddTab)(THIS, HWND hwnd) PURE;
    STDMETHOD(DeleteTab)(THIS, HWND hwnd) PURE;
    STDMETHOD(ActivateTab)(THIS, HWND hwnd) PURE;
    STDMETHOD(SetActiveAlt)(THIS, HWND hwnd) PURE;

    /* ITaskbarList2 */
    STDMETHOD(MarkFullscreenWindow)(THIS, HWND hwnd, BOOL fFullscreen) PURE;

    /* ITaskbarList3 */
    STDMETHOD(SetProgressValue)(THIS, HWND hwnd, ULONGLONG ullCompleted, 
ULONGLONG ullTotal) PURE;
    STDMETHOD(SetProgressState)(THIS, HWND hwnd, TBPFLAG tbpFlags) PURE;
    STDMETHOD(RegisterTab)(THIS, HWND hwndTab, HWND hwndMDI) PURE;
    STDMETHOD(UnregisterTab)(THIS, HWND hwndTab) PURE;
    STDMETHOD(SetTabOrder)(THIS, HWND hwndTab,HWND hwndInsertBefore) PURE;
    STDMETHOD(SetTabActive)(THIS, HWND hwndTab,HWND hwndMDI, TBATFLAG 
tbatFlags) PURE;
    STDMETHOD(ThumbBarAddButtons)(THIS, HWND hwnd,UINT cButtons, LPTHUMBBUTTON 
pButton) PURE;
    STDMETHOD(ThumbBarUpdateButtons)(THIS, HWND hwnd,UINT cButtons, 
LPTHUMBBUTTON pButton) PURE;
    STDMETHOD(ThumbBarSetImageList)(THIS, HWND hwnd, HIMAGELIST himl) PURE;
    STDMETHOD(SetOverlayIcon)(THIS, HWND hwnd, HICON hIcon, LPCWSTR 
pszDescription) PURE;
    STDMETHOD(SetThumbnailTooltip)(THIS, HWND hwnd, LPCWSTR pszTip);
    STDMETHOD(SetThumbnailClip)(THIS, HWND hwnd, RECT *prcClip);

    STDMETHOD(QueryContextMenu)(THIS_ HMENU,UINT,UINT,UINT,UINT) PURE;
    STDMETHOD(InvokeCommand)(THIS_ LPCMINVOKECOMMANDINFO) PURE;
    STDMETHOD(GetCommandString)(THIS_ UINT,UINT,PUINT,LPSTR,UINT) PURE;
    STDMETHOD(HandleMenuMsg)(THIS_ UINT,WPARAM,LPARAM) PURE;
  };
  #undef INTERFACE
#endif  /* __ITaskbarList3_INTERFACE_DEFINED__ */

static ITaskbarList3 *g_pTL = NULL;
static HWND           g_hwndConsole = NULL;
static int            TB_status = 0;

/* Use these macros to gets to the methods.
 */
#ifdef __cplusplus
  #define COCREATEINSTANCE(cls,iunk,ctx,iid,pv)      CoCreateInstance 
(cls,iunk,gtx,iid,pv)
  #define HRINIT(iface)                              iface->HrInit()
  #define RELEASE(iface)                             iface->Release()
  #define SETPROGRESSVALUE(iface,hwnd,permille,max)  iface->SetProgressValue 
(hwnd, permille, max)
  #define SETPROGRESSSTATE(iface,hwnd,state)         iface->SetProgressState 
(hwnd, state)
#else
  #define COCREATEINSTANCE(cls,iunk,ctx,iid,pv)      CoCreateInstance 
((REFCLSID)&(cls),iunk,ctx,(REFCLSID)&(iid),pv)
  #define HRINIT(iface)                              ITaskbarList3_HrInit 
(iface)
  #define RELEASE(iface)                             ITaskbarList3_Release 
(iface)
  #define SETPROGRESSVALUE(iface,hwnd,permille,max)  
ITaskbarList3_SetProgressValue (iface,hwnd,permille,max)
  #define SETPROGRESSSTATE(iface,hwnd,state)         
ITaskbarList3_SetProgressState (iface,hwnd,state)
#endif


void SetTBProgress (int permille)
{
  /* Already stopped; quit */
  if (g_pTL == NULL && permille < 0)
    return;

  /* Prior attempt failed; quit */
  if (TB_status != 0)
    return;

  /* Clamp to max 100% */
  if (permille > 1000)
    permille = 1000;

  /* 1st attempt; init */
  if (g_pTL == NULL) {
    HRESULT hr;

    g_hwndConsole = GetConsoleWindow();
    if (!g_hwndConsole) {
      TB_status = -1;
      return;
    }

    hr = CoInitializeEx (NULL, COINIT_APARTMENTTHREADED);
    if (!SUCCEEDED(hr)) {
      CoUninitialize();
      TB_status = -1;
      return;
    }
    COCREATEINSTANCE (CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER,
                      IID_ITaskbarList3, (void**)&g_pTL);
    if (g_pTL == NULL) {
      CoUninitialize();
      TB_status = -1;
      return;
    }

    hr = HRINIT (g_pTL);
    if (!SUCCEEDED(hr)) {
      TB_status = -1;
      RELEASE (g_pTL);
      g_pTL = NULL;
      CoUninitialize();
      return;
    }
    TB_status = 0;
  }

  if (permille >= 0) {
    SETPROGRESSVALUE (g_pTL, g_hwndConsole, permille, 1000);
  }
  else {
    SETPROGRESSSTATE (g_pTL, g_hwndConsole, TBPF_NOPROGRESS);
    RELEASE (g_pTL);
    g_pTL = NULL;
    CoUninitialize();
  }
}

Reply via email to