hDC меню

Тема в разделе "WASM.WIN32", создана пользователем cresta, 15 окт 2004.

  1. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Крамольный вопрос: можно ли в принципе получить hDC меню, чтобы нарисовать на нём? И если можно, то как? И вообще применимо ли hDC к меню? MSDN по этому поводу хранит молчание :-(
     
  2. vinnie_pooh

    vinnie_pooh New Member

    Публикаций:
    0
    Регистрация:
    30 июн 2004
    Сообщения:
    98
    Наверное, не самый красивый способ, но работает (почти):
    Код (Text):
    1. ULONG _stdcall ThreadProc(void*)
    2. {
    3.     HWND hMenu = FindWindowEx(NULL, NULL, "#32768", "");
    4.     if(hMenu)
    5.     {
    6.         HDC hDC = ::GetDC(hMenu);
    7.         if(hDC)
    8.         {
    9.             Rectangle(hDC, 0, 0, 10, 10);
    10.             ::ReleaseDC(hMenu, hDC);
    11.         }
    12.     }
    13.    return 1;
    14. }
    15.  
    16. LRESULT CMainFrame::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
    17. {
    18.     switch(message)
    19.     {
    20.     case WM_INITMENUPOPUP:
    21.         {
    22.             DWORD   ThreadId;
    23.             HANDLE  hThread;
    24.             hThread = CreateThread(0, 0, ThreadProc, NULL, 0, &ThreadId);
    25.             CloseHandle(hThread);
    26.         }
    27.         break;
    28.     }
    29.    
    30.     return CFrameWnd::WindowProc(message, wParam, lParam);
    31. }


    При первом клике на меню все функции в ThreadProc отрабатывают нормально, но на меню почему-то ничего не появляется, а если сдвинуть курсор на соседний POPUP (с File на Edit), то на нем рисуется квадратик.



    PS. Работает с первого раза, если убрать у меню эффект затемнения.
     
  3. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    cresta

    Простой способ - это использовать ownerdraw menu - можно рисовать только внутри пунктов меню.

    Сложный способ - ставить WH_CBT-hook, определять момент создания окна меню, подменять ему оконную процедуру, в своей реализовать обработку WM_PAINT, WM_NCPAINT и т.п.

    "Крутой" способ - создать собственное меню.
     
  4. Chib777

    Chib777 Александр

    Публикаций:
    0
    Регистрация:
    22 сен 2003
    Сообщения:
    82
    Адрес:
    Ukraine, Odessa
    cresta

    Как по мне то лучше использовать ownerdraw menu.

    Можешь поставить хук на класс окна меню, но там будет куча проблем. Наверно все проблемы решить можно, но терпение нужно хоорошее.

    О глючности можешь посудить на примере SDI. Cтиль меню xp с помощью хука+ownerdraw, а 2000 только ownerdraw.

    Там конечно ошибок немерянно, но всё же.

    [​IMG] _1838714826__SDI.zip
     
  5. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Спасибо, ребята, щас всё это буду жевать :)
     
  6. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Chib777



    Я пробовал это. Как SDI работает нормально, только вот пытался из VB вызывать ф-ции из XXMenu.dll - либо ф-ции возвращают 0 (судя по описанию-ошибка) либо возвращают 1 и прога виснет. Исходника dll нету, понять почему трудно :dntknw:



    vinnie_pooh



    Я вот не совсем уверен, что везде сработает CreateThread. Хочу сделать всё в dll, и если вызывать например из того же VB, CreateThread по-человечьи не работает.



    q_q





    Именно создавать меню, или обычное окно, дочернее к главному, замаскированое под меню? Если второе, то ничего умнее не придумал, чем создавать структуры наподобие такой



    MNUITEM STRUCT

    idItem DWORD ?

    nEnabledIcon DWORD ?

    nDisabledIcon DWORD ?

    CheckedState BYTE ?

    GrayedState BYTE ?

    lpMenuCaption DWORD ?

    ParentID DWORD ?

    ChildID DWORD ?

    MNUBUTTON ENDS



    и передавать такие структуры в процедуру, которая будет в соответствии с тем, как заполнена структура, создавать несколько окошек, имитирующих MenuBar, размещать их вверху ClientArea главного окна (или по позиции мыши, если contextMenu) и невидимые окна - собственно сами меню, которые будут отображаться по нажатию на MenuBar'e.



    Так я уже делал, но без пунктов, которые имеют child итемы. Или есть другие направления?
     
  7. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
  8. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Asterix

    Да, примерчик довольно простенький. Даже несколько игрушечный:) Делал такое, с прозрачностью, плавным опусканием сверху и нестандартным MenuBar'ом. Тут в аттаче лежит. Правда, только для 2000-ХР (прозрачность)



    Только не придумал, как по-человечески сделать субменю.

    [​IMG] _2100973564__CR N.zip
     
  9. Chib777

    Chib777 Александр

    Публикаций:
    0
    Регистрация:
    22 сен 2003
    Сообщения:
    82
    Адрес:
    Ukraine, Odessa
    cresta



    Я пробовал это. Как SDI работает нормально, только вот пытался из VB вызывать ф-ции из XXMenu.dll - либо ф-ции возвращают 0 (судя по описанию-ошибка) либо возвращают 1 и прога виснет.



    Ты наверно какието праметры неправильно передавал, я не знаю VB, но нужно очень внимательным быть с параметрами, поменяв местами хендл окна и меню, ничего работать не будет. Есть работающие примеры на C и Masm32. Там всё запускаеться в 9x,Win2000,XP.

    Работает также на Delphi.

    Глюков много, но тут на мой взгляд что то другое.

    У меня нет примера на VB, было б интересно глянуть.



    Исходника dll нету, понять почему трудно :dntknw:

    На форум нельзя вфложить, архив этого размера, выкладывать обрезки и просить что бы их собирали, некрасиво как то.

    Выложить в сорцы 2 месяца назад думал что рано, сейчас уже не заню, что то за последнее время толкового ничего не добавил.

    Эти сорцы есть у десятка людей я думаю, половины из них я вообще не заню, никакого секрета нет. Если нужны, напиши мне или мыло дай.



    Ты я вижу сделал что то грандиозное размер 111 кб, это на чём?

    Я не смог увидеть что, так как в XP, этот файл у меня вообще не запустился, сразу при запуске ошибка, приложение закрываеться. XP - SP1, толко поставил, никаких унфликтующих прог не ставил.
     
  10. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Chib777



    Добился, чтобы стиль включался :) Для всех параметров нужно передавать в dll адреса, а не сами значения. Стиль переключается, слева полоска вертикальная(где иконки должны быть), как положено, highlight тоже работает (рамочка на текущем пункте и выделение полупрозрачное). Теперь с передачей структуры MNUBUTTON повоевать надо. VB очень тяжело работает с указателями :-\ По поводу


    - может выслать ехе-файл, а то от самого текста толку может мало будет, если VB не установлен.

    Или текст, как вызывать ф-ции из dll?





    Может, сделать чтобы текст highlighted пункта другим цветом рисовался? Это как пожелание. Видел такое - довольно симпатично.



    А что касается 111 кБ, то это каркас программы (не только меню) Был написан на PowerBasic (есть такой продукт). Когда-то пользовался им, потом из-за непредсказуемых глюков забросил :dntknw: Компилера от него сейчас нету, перекомпилить, чтобы подправить - возможности нет. Увы.
     
  11. Chib777

    Chib777 Александр

    Публикаций:
    0
    Регистрация:
    22 сен 2003
    Сообщения:
    82
    Адрес:
    Ukraine, Odessa
    cresta

    Добился, чтобы стиль включался :) Для всех параметров нужно передавать в dll адреса, а не сами значения...



    Я думаю что для примера взял бы каркас, пришли что есть интересное - текст подключения, вызова, на chib_odessa()bk.ru или XXControls@bk.ru.



    Может, сделать чтобы текст highlighted пункта другим цветом рисовался? Это как пожелание. Видел такое - довольно симпатично.



    Там цвет изменяеться в зависимости от текущей установленной темы.

    Как вычислять цвета настоящего стиля XP, я нигде не нашёл. Поэтому методом подбора вычислил похожие.
     
  12. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Chib777



    Сделал маленький проектик (там и компилированный ехе). Если msvbvm60.dll есть, то в принципе должно работать. Сам код в файле .frm можно в блокноте посмотреть, если VB6 нету. Отправил на XXControls



    Там же в папке рисунок другого меню. С выделением цветом (правда, рисунок исказился, когда его сохранял в файл, в деле он гораздо красивее). Это делает cPopMenu6.dll (ActiveX)+ SsubTmr.dll (тоже ActiveX). Эти две .dll весят суммарно 160 кБ. Плюс их надо регистрировать в реестре. А так вроде неплохая штука. Также может замостить бэкграунд рисунком, сделать выделение в виде градиента. Если интересно, я тогда еще тестовый сделаю с этими .dll и вышлю.
     
  13. masquer

    masquer wasm.ru

    Публикаций:
    0
    Регистрация:
    13 сен 2002
    Сообщения:
    890
    Адрес:
    Николаев




    RTFM. Для меню есть константы типа COLOR_MENU, COLOR_MENUHILIGHT и пр. Для каждой темы они свои, велосипед не стоит выдумывать :)
     
  14. Chib777

    Chib777 Александр

    Публикаций:
    0
    Регистрация:
    22 сен 2003
    Сообщения:
    82
    Адрес:
    Ukraine, Odessa
    cresta

    Сорц получил, огромное спасибо. VB6 у меня есть (пылиться уже 2 года), я чуть позже поставлю и посмотрю.



    Там же в папке рисунок другого меню.

    По рисунку, я многое не увижу. Интересно было бы глянуть в работе это меню. Мог бы ты выслать, исполняемый файл + требуемые dll.



    Также может замостить бэкграунд рисунком, сделать выделение в виде градиента

    Да это, интересная идея + прозрачность. Но дело в том что стиль XP, нестабилен. Там пару процедур надо доделать. Процедура окна меню, сделана плоховато.



    masquer



    RTFM. Для меню есть константы типа COLOR_MENU, COLOR_MENUHILIGHT и пр. Для каждой темы они свои, велосипед не стоит выдумывать :)



    В стиле 2000, я использую константы системных цветов, это понятно.

    Но в стиле XP (под стилем XP, понимаю стиль как в VisualStudio.net) не используються чисто ситемные цвета, там из этих цветов генерируються новые. Это я проверял, методом тыка.

    Даже на глаз видно что системные цвета, и цвета меню того же VisualStudio не совпадают.

    Формул смеси системных цветов, что бы цвета точно совпадали я не нашёл.

    В сорце NewMenu (C++), вроде неплохой вариант используеться.
     
  15. masquer

    masquer wasm.ru

    Публикаций:
    0
    Регистрация:
    13 сен 2002
    Сообщения:
    890
    Адрес:
    Николаев
    Chib777



    Мм, тогда изучай библиотеку UxTheme.dll - все это там есть, смотри в MSDN. Мне просто для меню этих констант для нормальной работы в ХР хватало.

    Утечки GDI, кстати, уже пофиксены?
     
  16. Chib777

    Chib777 Александр

    Публикаций:
    0
    Регистрация:
    22 сен 2003
    Сообщения:
    82
    Адрес:
    Ukraine, Odessa
    masquer



    Утечки GDI, кстати, уже пофиксены?



    Утечки как бы устарнены, но ив то же время осталась одна непонятная.

    Запускаю прогу с меню - SDI, напр., стиль XP по умолчанию, бегаю по пунктам меню

    верхнего уровня, с объектами всё нормально.

    Открываю всплывающее меню, например FILE, после этого добавляеться к общему числу

    объектов GDI используемых прогой одна кисточка, закрываю меню, она так и висит за прогой,

    открываю это же меню, ещё раз, ещё одна добавилась, и так раз 5 - 6, а потом нормально и число кисточек

    не растёт, число объектов используемых прогой стабильно. Это непонятка висит уже год, но уже смирился.

    Потому что я везде проверил, все кисточки я удаляю, пробовал даже по 2 раза.

    Это что то с контекстом который, предоставляеться DRAWITEMSTRUCT, к такому выводу я пришёл.

    Проверял я это всё прогой Фень Юаня GDIObj, что с книгой идёт.
     
  17. Chib777

    Chib777 Александр

    Публикаций:
    0
    Регистрация:
    22 сен 2003
    Сообщения:
    82
    Адрес:
    Ukraine, Odessa
    cresta

    Напиши мне пожалуйста пустое письмо.

    У меня произошла небольшая неприятность с почтой и последние, адреса почты удалились. У меня теперь нет твоего мыльника.



    Все архивы получил, огромное спсибо.