Re: Прорисовка меню
От: Vis Украина  
Дата: 06.11.09 01:45
Оценка:
Здравствуйте, Glas, Вы писали:

G>Столкнулся с такой проблемой. Создан класс на основе CMenu с перегруженной функцией DrawItem. В ней, помимо отрисовки итемов меню, задаю стиль окна этой самой меню(прозрачность и регион), но при вызове этой самой меню сначала появляется меню без изменений и лишь когда наводишь мышь оно резко меняется. Пробовал отловить сообщения OnInitMenu и OnInitPopupMenu не помогло, меняется главное диалоговое окно, а не меню. Где еще можно отловить инициализацию окна меню?


Я думаю, придется это делать через хук.
Вот здесь кусок кода..

HHOOK CFlatMenu::m_hHook = NULL;

const TCHAR _WndPropName_OldProc[] = _T("XPWndProp_OldProc");
const TCHAR _WndPropName_MenuXP[] = _T("XPWndProp_MenuXP");


LRESULT CALLBACK CFlatMenu::FlatMenuWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    WNDPROC oldWndProc = (WNDPROC)::GetProp (hWnd, _WndPropName_OldProc);

    //LPWINDOWPOS lpPos;
    switch ( uMsg )
       {                    
        case WM_СREATE:
                   // Тебе сюды.
        break;
    }

    return CallWindowProc(oldWndProc, hWnd, uMsg, wParam, lParam);    
}


LRESULT CALLBACK CFlatMenu::HookProc(int code, WPARAM wParam, LPARAM lParam)
{
    TCHAR sClassName[10];
    CWPSTRUCT* pStruct = (CWPSTRUCT*)lParam;

    // Not a real loop (just for 'break' branchment)
    while ( code == HC_ACTION )
    {
        HWND hWnd = pStruct->hwnd;

        int Count = ::GetClassName (hWnd, sClassName, sizeof(sClassName)/sizeof(TCHAR));
        
        // Check for the menu-class
        if ( Count != 6 || _tcscmp (sClassName, _T("#32768")) != 0 )
        {            
            break;
        }        
        // Normal and special handling for menu 0x10012
        if ( pStruct->message != WM_CREATE && pStruct->message != WM_NCCREATE && pStruct->message != 0x01E2 )
        {
            break;
        }               
        
        //VERIFY(CWndMenuXP::FromHandle (pStruct->hwnd, false) != NULL);

        if ( ::GetProp (pStruct->hwnd, _WndPropName_OldProc) != NULL )
        {
            // Already subclassed
            break;
        }
        // Subclass the window
        WNDPROC oldWndProc = (WNDPROC)(LONG_PTR)::GetWindowLong (pStruct->hwnd, GWL_WNDPROC);

        if ( oldWndProc == NULL )
        {
            break;
        }
        ASSERT(oldWndProc != FlatMenuWndProc);

        if ( !SetProp (pStruct->hwnd, _WndPropName_OldProc, oldWndProc) )
        {
            break;
        }

        if ( !SetWindowLong (pStruct->hwnd, GWL_WNDPROC,(DWORD)(DWORD_PTR)FlatMenuWndProc) )
        {
            ::RemoveProp (pStruct->hwnd, _WndPropName_OldProc);
            break;
        } 
    
        ATLTRACE(_T("Success\r\n"));    
        // Success !
        break;
    }

    return CallNextHookEx (m_hHook, code, wParam, lParam);
}

void CFlatMenu::InitializeHook()
{
    m_hHook = SetWindowsHookEx(WH_CALLWNDPROC, HookProc, NULL, ::GetCurrentThreadId());
}

void CFlatMenu::UninitializeHook()
{
    UnhookWindowsHookEx(m_hHook);
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.