I've checked out the Microsoft documentation however it states that tthere shouldn't be difference.

Observe that this can be a virtual ListView, and so i give you the condition icon index within the code applying the LVN_GETDISPINFO message, when the LVIF_Condition flag is occur LV_ITEM::mask.

Does anybody are conscious of any subtle variations which might cause this difference in behavior?

Not posting any sample code inside your question doesn't exactly help...

This code works best for me:

enter image description here

#include <Windows.h>
#include <commctrl.h>
#pragma comment(lib, "comctl32.lib")

typedef struct {
    LPTSTR text;
    UINT icon;
    UINT stateicon;
} MYITEM;
HWND g_hLV=NULL;
MYITEM g_myitems[2]={{"item1",0,0},{"item2",2,2}};

LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp) 
{
    switch(msg) 
    {
    case WM_NOTIFY:
        if (lp) 
        {
            NMLVDISPINFO*pLVDI=(NMLVDISPINFO*)lp;
            NMLISTVIEW*&pLV=(NMLISTVIEW*&)pLVDI;
            switch(pLVDI->hdr.code) 
            {
            case LVN_GETDISPINFO:
                if (LVIF_TEXT&pLVDI->item.mask) pLVDI->item.pszText=g_myitems[pLVDI->item.iItem].text;
                if (LVIF_IMAGE&pLVDI->item.mask) pLVDI->item.iImage=g_myitems[pLVDI->item.iItem].icon;
                if (LVIF_STATE&pLVDI->item.mask) 
                {
                    pLVDI->item.state=INDEXTOSTATEIMAGEMASK(1+g_myitems[pLVDI->item.iItem].stateicon);
                    pLVDI->item.stateMask=pLVDI->item.state;
                }
                return 0;
            }
        }
        break;
    case WM_CREATE:
        {
            g_hLV=CreateWindowEx(WS_EX_CLIENTEDGE,WC_LISTVIEW,0,WS_VISIBLE|WS_CHILD|LVS_OWNERDATA|LVS_REPORT|LVS_SHAREIMAGELISTS,0,0,0,0,hwnd,0,0,0);
            LVCOLUMN lvc={LVCF_TEXT|LVCF_WIDTH};
            lvc.pszText="dummy";
            lvc.cx=99;
            ListView_InsertColumn(g_hLV,0,&lvc);
            SHFILEINFO sfi;
            HIMAGELIST hil=(HIMAGELIST)SHGetFileInfo(".\\",FILE_ATTRIBUTE_DIRECTORY,&sfi,0,SHGFI_SMALLICON|SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES);
            ListView_SetImageList(g_hLV,hil,LVSIL_SMALL);
            ListView_SetImageList(g_hLV,hil,LVSIL_STATE);
            g_myitems[1].stateicon=g_myitems[1].icon=sfi.iIcon;//assuming the imagelist has icons is wrong, so set at least one of them to a valid index
            ListView_SetCallbackMask(g_hLV,LVIS_STATEIMAGEMASK);
            ListView_SetItemCount(g_hLV,2);
        }
        return 0;
    case WM_SIZE:
        SetWindowPos(g_hLV,0,0,0,LOWORD(lp),HIWORD(lp),SWP_NOZORDER|SWP_NOACTIVATE);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    }
    return DefWindowProc(hwnd,msg,wp,lp);
}

int WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd) 
{
    InitCommonControls();
    //This dialog subclassing is a ugly hack, but this is just sample code!
    HWND hwnd=CreateWindowEx(0,WC_DIALOG,"LVTest",WS_OVERLAPPEDWINDOW,0,0,99,99,0,0,0,0);
    SetWindowLongPtr(hwnd,GWLP_WNDPROC,(LONG_PTR)WndProc);
    SendMessage(hwnd,WM_CREATE,0,0);
    ShowWindow(hwnd,nShowCmd);
    MSG msg;
    while (GetMessage(&msg,0,0,0) > 0) 
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}