Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > Всё таки есть проблема срезания!!!


Автор: takedo 30.6.2006, 13:27
Ещё раз добрый день!
Всё таки проблема со срезанием не исчезла! Проблема думаю в том, что кнопку я все равно создаю через Create, где задаю таки прямоугольник!!! Он то и перерисовывается когда поверх моего диалога появляется другое окно. Результат - bad.jpd из quest1.rar/
Кому не понятно, напоминаю, что я создал кнопки в виде шестигранников, помещаю их рядом друг с другом и при выполнении описанных событий http://forum.vingrad.ru/index.php?showtopic=102357 получаем вид с пятью кнопками, присоединенный к этому топику. Как избавиться от такого???  smile  Помогитеееее. smile  

Автор: takedo 30.6.2006, 13:43
и ещё!!! Например, жёлтая кнопка не отраатывает нажатие мышью в "верхнем треугольнике", который накрывается верхними кнопками(их прямоугольниками CRect, которые передавались в Create). Нажатие мыши отрабатываю так:
Код

void M6Button::OnLButtonUp(UINT nFlags, CPoint point)
{
    // TODO: Add your message handler code here and/or call default
    if(m_region.PtInRegion(point))
    {
        CButton::OnLButtonUp(nFlags, point);
    }
}

void M6Button::OnLButtonDown(UINT nFlags, CPoint point)
{
    // TODO: Add your message handler code here and/or call default
    if(m_region.PtInRegion(point))
    {
        CButton::OnLButtonDown(nFlags, point);
    }
}


Как со всем этим бороться??? Кто нибудь ведь наверняка только и занимается тем, что рисует и использует кнопки разного вида smile Помогите, ато уже и не знаю совсем как быть! smile  

Автор: Earnest 30.6.2006, 14:39
С перекрытием экстентов кнопок попробуй бороться с помощью стиля WS_EX_TRANSPARENT. Но не уверена. У нас нынче Coocky специалист по хитрым кнопкам.
А может, нужно в OnEraseBkgnd кнопок устанавливать ClipRegion, оставляя только шестиугольник.

Что касается мыши - думаю, что нужно ее обрабатывать на PretranslateMessage диалога:
выяснить, в чей регион попадает кнопка, и послать этому контролу сообщение WM_LBUTTONDOWN или что там. 

Автор: takedo 30.6.2006, 15:22
Пока шел домой, вспомнил о том, что Coocky чего то там писал похожее, а про обработку сообщения в родителе - похоже это единственное... Ща буду пробовать. Спасибо, но вопрос пока не снят

Добавлено @ 15:29 
так, первая проблема ушла вместе с факом Coocky http://forum.vingrad.ru/index.php?showtopic=99226 WM_ERASEBKGRD - возвращаем истину и прямоугольник не заливается. Осталось с нажатием определиться. smile  

Автор: takedo 30.6.2006, 15:43
начал делать в PreTranslateMessage и понял, что не знаю, где взять координаты при событии WM_LBUTTONUP smile У кого нибудь есть идеи?

Добавлено @ 15:47 
похоже координаты передаются в Screen в pMsg->pt

Добавлено @ 15:53 
ещё lParam в нижней части содержит x, в верхней - y уже в "местных" координатах. smile  Так и дойдем потихоньку до решения smile  

Автор: takedo 30.6.2006, 16:14
Все, определяю какая кнопка нажата, но вот не получается правильно перенаправить сообщение!!!
Код

BOOL CbuttonscolDlg::PreTranslateMessage(MSG* pMsg)
{
    // TODO: Add your specialized code here and/or call the base class
    if(pMsg->message == WM_LBUTTONUP)
    {
        WORD xPos;
        WORD yPos;
        xPos = LOWORD(pMsg->lParam);
        yPos = HIWORD(pMsg->lParam);
        for(int i=0;i<5;i++)
        {
            if(b6[i].InRgn(xPos,yPos))
            {
                //как правильно перенаправить сообщение???
            }
        }
    }
    return CDialog::PreTranslateMessage(pMsg);
}

Help Me пожалуйтса smile  

Автор: Earnest 30.6.2006, 17:18
pButton->SendMessage (pMsg->message,pMsg->wParam,MAKELPARAM(x,y));
Только x, y нужно пересчитать в кординаты контрола.

И еще, позиция (lParam) приходит в клиентских координатах той кнопки, которой предназначено сообщение, т.е. pMsg->hWnd. Тебе нужно перевести их в координаты парента, перед тем, как анализировать попадание. Для этого удобно использовать MapWindowPoints. Но лучше действительно использовать pMsg->pt - там координаты всегда экранные. Примерно так:
Код

BOOL CMyDialog::PreTranslateMessage (LPMSG pMsg)
{
   if (pMsg->message >= WM_MOUSEFIRST && pMsg->message <= WM_MOUSELAST)
   {
      CPoint pt = pMsg->pt;
      ScreenToClient(pt);
      CWnd* pBtn = FindButton (pt);   // это твоя функция поиска
      if (pBtn)
      {
          CPoint pt = pMsg->pt;
           pBtn->ScreenToClient(pt);
           pBtn->SendMessage (pMsg->message,pMsg->wParam,MAKELPARAM(pt.x,pt.y));
          return TRUE;
      }
   }
   return FALSE;
}
 

Автор: takedo 30.6.2006, 20:20
сделал так:
Код

BOOL CbuttonscolDlg::PreTranslateMessage(MSG* pMsg)
{
    // TODO: Add your specialized code here and/or call the base class
    if(pMsg->message == WM_LBUTTONUP)
    {
        CPoint pt = pMsg->pt;
        ScreenToClient(&pt);        
        for(int i=0;i<5;i++)
        {
            if(b6[i].InRgn(pt.x,pt.y))
            {
    TRACE("\nкнопка%d\n",i);
    b6[i].SendMessage (pMsg->message,pMsg->wParam,MAKELPARAM(pt.x,pt.y));
    return TRUE;
            }
        }
    } 
    return CDialog::PreTranslateMessage(pMsg);
}

в TRACE всегда определяется четко! Но при работе с SendMessage всё равно работает коряво! То кнопка не нажимается, то все таки загорается нажатой не желтая, а красная или зеленая., а если не отображаются верхние как нажатые, то бывает, что когда подводишь на них мышь - они тут же отображаются как нажатые. Ничего понять не могу... 

Автор: takedo 30.6.2006, 21:19
сделал так:
Код

BOOL CbuttonscolDlg::PreTranslateMessage(MSG* pMsg)
{
    // TODO: Add your specialized code here and/or call the base class
    if(pMsg->message == WM_LBUTTONUP)
    {
        CPoint pt = pMsg->pt;
        ScreenToClient(&pt);        
        for(int i=0;i<5;i++)
        {
            if(b6[i].InRgn(pt.x,pt.y))
            {
                //как правильно перенаправить сообщение???
                //TRACE("\nкнопка%d\n",i);
                b6[i].SetState(FALSE);
                b6[i].SetFocus();
                return TRUE;
            }
        }
    } 
    if(pMsg->message == WM_LBUTTONDOWN)
    {
        CPoint pt = pMsg->pt;
        ScreenToClient(&pt);        
        for(int i=0;i<5;i++)
        {
            if(b6[i].InRgn(pt.x,pt.y))
            {
                //как правильно перенаправить сообщение???
                //TRACE("\nкнопка%d\n",i);
                b6[i].SetState(TRUE);
                b6[i].SetFocus();
                return TRUE;
            }
        }
    } 
    return CDialog::PreTranslateMessage(pMsg);
}

работает как и хотел, но не покидает ощущение, что как то не так сделано, через одно место похоже... Если можно это улучшить - то не стесняйтесь. smile 
Да, Coocky  и Earnest просто так по плюсику - люблю я вас smile  

Автор: Earnest 1.7.2006, 17:26
За любовь спасибо  smile , но я бы все же обрабатывала не только BUTTONUP, а все мышиные сообщения. Чтобы кнопка сама все обработала стандартно, она должна получить весь комплект: и DOWN, и UP. Я бы еще и MouseMove добавила до кучи: вдруг захочется сделать, чтобы кнопка загоралась, когда над ней мыша.

Добавлено @ 17:28 
Попробуй сделать как у меня в примере. Что тебя останавливает? Неужели думаешь, что тормозить будет? 

Автор: takedo 1.7.2006, 20:11
Earnest, Да нет, ничего такого я не думаю, так и делал вначале. Только мне похоже не понадобится загорание кнопок - это уже слишком! Эти кнопки и так будут загораться кучей цветов в зависимости от состояния => возможно умру делая ещё и mousemove. Но захочу посуицидить - займусь smile  smile .
Одно толко плохо(это очень серьезно): получается, что в винде можно сделать нормальный контроль, то есть самодостаточный как CButton только в случае, когда объект создается в прямоугольнике!!!!!!!!!!!!!!! Когда я начинал делать шестигранную кнопку думал, что она будет самодостаточна smile , а получается, что надо делать сразу набор кнопок на CWnd - только это будет более менее самодостаточный объект! Чё с ентим делать??? Последний вопрос видимо риторический.... smile

Добавлено @ 20:15 
Earnest, Кстати, вот почему не сделал(вспомнил!!! smile ) я же запарился передавать координаты! И все равно получалось, что другие кнопки отрабатывались, а здесь я четко посылаю тому кому надо. Вот ещё заменю SetFocus и SetState на посылку сообщения через SendMessage и усё! 
Я ведь кстати чего спрашивал? Мне казалось, что так как у меня написано несколько кривовато, так кривовато или нет? Как принято писать у профи? smile  

Автор: takedo 2.7.2006, 10:53
самое смешное, что я отказался от применения этих шестиугольных кнопок! smile  smile  smile  smile. Но тема закрыта раньше smile

Добавлено @ 10:54 
 smile  

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)