taskbar item drag problem

Newbie Spellweaver
Joined
Oct 4, 2022
Messages
53
Reaction score
105
Hey guys,


I’m working on a new taskbar and everything is working fine so far, but there’s this one annoying bug that I can’t figure out.

Just like the original taskbar, when you drag an item outside of the taskbar rectangle, it should disappear and get removed from the taskbar. That part works perfectly on the normal taskbar.

I added a custom slider that basically reuses the same logic as the main taskbar and runs through the CWndTaskbar class but here it wont work :


For the slider though, I need to define specific coordinates to create a pickup space, so you can only resize it when you click and drag on a certain area of the taskbar.

Here’s where the problem starts:
C++:
BOOL CWndTaskBarSlider::IsPickupSpace(CPoint point)
{
    CRect rect = GetWindowRect();
    rect.right = 25;
    if( rect.PtInRect( point ) )
    {
        return TRUE;
    }
    return FALSE;
}

When I hook the virtual BOOL IsPickupSpace, set the position, and return the bool, I suddenly can’t drag items out of the window anymore. Instead, I just get the red “forbidden” cursor , basically like SetForbid(TRUE); is being triggered.

If I don’t hook BOOL IsPickupSpace, everything works fine and I can drag items out of the taskbar without any issues :


So it definitely seems related to that call, but I’m honestly kind of lost on what exactly is causing it. Since others have worked with the taskbar before, I was hoping someone might have run into this issue already and could point me in the right direction before i waste more time on this.

Any ideas would be really appreciated.

Im pretty sure this is not the problem but onDropIcon :

C++:
BOOL CWndTaskBarSlider::OnDropIcon(LPSHORTCUT pShortcut, CPoint point)
{
    CRect wndRect = GetWindowRect();
    wndRect.DeflateRect(3, 3);

    if (pShortcut->m_pFromWnd == this)
    {
        LPSHORTCUT lpShortcut = (LPSHORTCUT)pShortcut->m_dwData;

        if (!GetClientRect().PtInRect(point))
        {
            switch (lpShortcut->m_dwData)
            {
                case 0: g_DPlay.SendRemoveAppletTaskBar((BYTE)lpShortcut->m_dwIndex); break;
                case 1: g_DPlay.SendRemoveItemTaskBar(g_WndMng.m_pWndTaskBar->m_nSlotIndex, (BYTE)lpShortcut->m_dwIndex); break;
                case 2: g_WndMng.m_pWndTaskBar->RemoveSkillQueue(lpShortcut->m_dwIndex); return TRUE;
            }
            lpShortcut->Empty();
            return TRUE;
        }
    }
   

    CWndBase* pWndFrame = pShortcut->m_pFromWnd->GetFrameWnd();
    if (pWndFrame &&
        pWndFrame != this &&
        pWndFrame->GetWndId() != APP_INVENTORY &&
        pWndFrame->GetWndId() != APP_COMMUNICATION_CHAT &&
        pWndFrame->GetWndId() != APP_SKILL4 &&
        pWndFrame->GetWndId() != APP_MOTION &&
        pWndFrame->GetWndId() != APP_PARTY &&
        pWndFrame->GetWndId() != APP_LORD_SKILL &&
        pWndFrame->GetWndId() != APP_TASKBAR16
    )
    {
        SetForbid(TRUE);
        return FALSE;
    }


    if (pShortcut->m_dwShortcut == SHORTCUT_SKILL && pShortcut->m_dwType != 2)
    {
        LPSKILL pSkill = g_pPlayer->GetSkill(0, pShortcut->m_dwId);
        if (!pSkill || pSkill->dwLevel <= 0 || !g_pPlayer->CheckSkill(pSkill->dwSkill))
        {
            SetForbid(TRUE);
            return FALSE;
        }
    }

    if (pShortcut->m_dwId == 0 &&
        strlen(pShortcut->m_szString) < 1 &&
        pShortcut->m_dwShortcut != SHORTCUT_SKILLFUN &&
        pShortcut->m_dwShortcut != SHORTCUT_LORDSKILL)
    {
        SetForbid(TRUE);
        return FALSE;
    }

    for (int i = 0; i < CWndTaskBar::CONST_MAX_APPLET; ++i)
    {
        CRect rect(GetAppletSlotPosition(i), CSize(CWndTaskBar::CONST_ICON_SIZE, CWndTaskBar::CONST_ICON_SIZE));

        if (rect.PtInRect(point))
        {
            if (pShortcut->m_pFromWnd == this)
            {
                LPSHORTCUT lpCurShortcut = (LPSHORTCUT)pShortcut->m_dwData;
                if (&g_WndMng.m_pWndTaskBar->m_aSlotApplet[i] == lpCurShortcut)
                    return FALSE;
            }

            if (pShortcut->m_dwShortcut == SHORTCUT_CHAT)
            {
                CString sChat = m_GlobalShortcut.m_szString;
                sChat.Replace("--", "");
                sChat.Replace("'", "");
                sChat.Replace("/*", "");
                sChat.Replace("*/", "");
                strcpy(m_GlobalShortcut.m_szString, (const char*)sChat);
            }
            else if (pShortcut->m_dwShortcut == SHORTCUT_SKILL)
            {
                ItemProp* pProp = (pShortcut->m_dwType == 2) ?
                                  prj.GetPartySkill(pShortcut->m_dwId) :
                                  prj.GetSkillProp(g_pPlayer->GetSkill(0, pShortcut->m_dwId)->dwSkill);

                if (pProp->dwComboStyle != CT_STEP && pProp->dwComboStyle != CT_GENERAL)
                {
                    SetForbid(TRUE);
                    return FALSE;
                }
            }

            g_WndMng.m_pWndTaskBar->SetShortcut(i, pShortcut->m_dwShortcut, pShortcut->m_dwType, pShortcut->m_dwId, pShortcut->m_pTexture, 0);
            break;
        }
    }

    if (pShortcut->m_pFromWnd == this)
    {
        LPSHORTCUT lpShortcut = (LPSHORTCUT)pShortcut->m_dwData;
        switch (lpShortcut->m_dwData)
        {
            case 0: g_DPlay.SendRemoveAppletTaskBar((BYTE)lpShortcut->m_dwIndex); break;
            case 1: g_DPlay.SendRemoveItemTaskBar(g_WndMng.m_pWndTaskBar->m_nSlotIndex, (BYTE)lpShortcut->m_dwIndex); break;
            case 2: g_WndMng.m_pWndTaskBar->RemoveSkillQueue(lpShortcut->m_dwIndex); return TRUE;
        }
        lpShortcut->Empty();
    }
    return TRUE;
}

EDIT :

I think I found a fix.
I removed the IsPickupSpace call and instead added an m_bCanResize bool inside the CWndTaskbarSlider class.
I’m setting it in OnLButtonDown and OnLButtonUp, then just hardcoding it into the resize logic.

C++:
void CWndTaskBarSlider::OnLButtonDown(UINT nFlags, CPoint point)
{
    CRect rect = GetWindowRect();
    rect.right = 25;

    if( rect.PtInRect( point ) )
        m_bCanResize = true;

    m_pSelectShortcut = Select(point);
}
void CWndTaskBarSlider::OnLButtonUp(UINT nFlags, CPoint point)
{
    m_bCanResize = false;
    LPSHORTCUT pShortcut = Select(point);
   
    if (pShortcut && pShortcut == m_pSelectShortcut && !pShortcut->IsEmpty() && pShortcut->m_dwData != 2)
        g_WndMng.ObjectExecutor(pShortcut);
}


C++:
if( GetWndId() == APP_TASKBARSLIDE )
            {
                if ( g_WndMng.m_pWndTaskBarSlider->m_bCanResize )
                {
                    CPoint pt = point - m_pointOld;
                    int w = rectWnd.Width();
                    int h = rectWnd.Height();

                    CRect rect = m_pWndRoot->GetLayoutRect();
                    if( pt.x < rect.left && pt.x > rect.left ) pt.x = rect.left;
                    if( pt.x + w > rect.right && pt.x + w < rect.right  ) pt.x = rect.right - w;
                    if( pt.x < rect.left ) pt.x = rect.left;
                    if( pt.x + w > rect.right  ) pt.x = rect.right - w;

                    pt.y = rect.bottom -  60 - 4;
                   
                    rectWnd.SetRect( pt.x, pt.y, pt.x + w, pt.y + h );

                    CWndTaskBar* pWndTB = (CWndTaskBar*)g_WndMng.GetWndBase(APP_TASKBAR16);
                    CRect rectRoot = m_pWndRoot->GetLayoutRect();
                    CRect RectpWndTB = pWndTB->GetWndRect();

                    rectWnd.right = RectpWndTB.left + 2;


                    if(rectWnd.left < (RectpWndTB.left - 392))
                        rectWnd.left = RectpWndTB.left - 392;

                    if((rectWnd.left + 21) > RectpWndTB.left)
                        rectWnd.left = RectpWndTB.left - 21;

                    SetWndRect( rectWnd, TRUE );
                    g_Option.m_nWidthSlideBar = rectWnd.Width();
                }
            }

Seems to be working so far 👍
 
Last edited:
Solution
EDIT :

I think I found a fix.
I removed the IsPickupSpace call and instead added an m_bCanResize bool inside the CWndTaskbarSlider class.
I’m setting it in OnLButtonDown and OnLButtonUp, then just hardcoding it into the resize logic.

C++:
void CWndTaskBarSlider::OnLButtonDown(UINT nFlags, CPoint point)
{
    CRect rect = GetWindowRect();
    rect.right = 25;

    if( rect.PtInRect( point ) )
        m_bCanResize = true;

    m_pSelectShortcut = Select(point);
}
void CWndTaskBarSlider::OnLButtonUp(UINT nFlags, CPoint point)
{
    m_bCanResize = false;
    LPSHORTCUT pShortcut = Select(point);
  
    if (pShortcut && pShortcut == m_pSelectShortcut && !pShortcut->IsEmpty() && pShortcut->m_dwData != 2)...
EDIT :

I think I found a fix.
I removed the IsPickupSpace call and instead added an m_bCanResize bool inside the CWndTaskbarSlider class.
I’m setting it in OnLButtonDown and OnLButtonUp, then just hardcoding it into the resize logic.

C++:
void CWndTaskBarSlider::OnLButtonDown(UINT nFlags, CPoint point)
{
    CRect rect = GetWindowRect();
    rect.right = 25;

    if( rect.PtInRect( point ) )
        m_bCanResize = true;

    m_pSelectShortcut = Select(point);
}
void CWndTaskBarSlider::OnLButtonUp(UINT nFlags, CPoint point)
{
    m_bCanResize = false;
    LPSHORTCUT pShortcut = Select(point);
  
    if (pShortcut && pShortcut == m_pSelectShortcut && !pShortcut->IsEmpty() && pShortcut->m_dwData != 2)
        g_WndMng.ObjectExecutor(pShortcut);
}


C++:
if( GetWndId() == APP_TASKBARSLIDE )
            {
                if ( g_WndMng.m_pWndTaskBarSlider->m_bCanResize )
                {
                    CPoint pt = point - m_pointOld;
                    int w = rectWnd.Width();
                    int h = rectWnd.Height();

                    CRect rect = m_pWndRoot->GetLayoutRect();
                    if( pt.x < rect.left && pt.x > rect.left ) pt.x = rect.left;
                    if( pt.x + w > rect.right && pt.x + w < rect.right  ) pt.x = rect.right - w;
                    if( pt.x < rect.left ) pt.x = rect.left;
                    if( pt.x + w > rect.right  ) pt.x = rect.right - w;

                    pt.y = rect.bottom -  60 - 4;
                  
                    rectWnd.SetRect( pt.x, pt.y, pt.x + w, pt.y + h );

                    CWndTaskBar* pWndTB = (CWndTaskBar*)g_WndMng.GetWndBase(APP_TASKBAR16);
                    CRect rectRoot = m_pWndRoot->GetLayoutRect();
                    CRect RectpWndTB = pWndTB->GetWndRect();

                    rectWnd.right = RectpWndTB.left + 2;


                    if(rectWnd.left < (RectpWndTB.left - 392))
                        rectWnd.left = RectpWndTB.left - 392;

                    if((rectWnd.left + 21) > RectpWndTB.left)
                        rectWnd.left = RectpWndTB.left - 21;

                    SetWndRect( rectWnd, TRUE );
                    g_Option.m_nWidthSlideBar = rectWnd.Width();
                }
            }

Seems to be working so far 👍
☝️
 
Upvote 0
Solution
But yeah the band-aid fix is a solution for now but if anyone knows the root issue of this feel free to explain it :D

My guess is it has something to do with window focus stuff
 
Upvote 0
Back