Вывод текста с прозрачным фоном

Тема в разделе "WASM.WIN32", создана пользователем da-007, 29 сен 2006.

  1. da-007

    da-007 New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    13
    Добрый день.

    Люди добрые, мы сами не местные, помогите решить проблему. Ситуация: есть окно. На нем, для оформления, создано несколько дочерних окон, которым назначены bmp-картинки (назовем это скинами) - это все в порядке, это все работает. Проблема вот в чем: нужно несколько раз в секунду выводить на это окно текстовую информацию, не "портя" скинов. Т.е. у текста должен быть прозрачный фон. Вот тут, собственно и затык... Информации у меня мало, подскажите пожалуйста, как правильные программисты решают этот вопрос? Пытался создать дочернее окно, на нем "SetBkMode (hDC,TRANSPARENT);", но уперся в то, что не могу очистить контекст после предыдущего рисования... Пытался сперва вывести на дочернее окно кусочек фона, а потом текст, уперся в то, что DrawText не выводит (?) текст на контекст в памяти, которому уже назначена (SelectObject) картинка (что, в общем, логично). В-общем, единственное, чего я добился: сперва выводим на контекст окна кусочек фона, а потом на него же выводим текст. И в итоге получаем мерцание :dntknw:

    И попутно два вопроса:

    1. Как я понял MSDN,

    "ValidateRect (hWnd,false);"

    и

    "BeginPaint (hWnd,PaintStruct);
    EndPaint (hWnd,PaintStruct);"

    это полностью одинаковые "вещи", т.е. обе делают одно и то же: говорят винде, что наше окно полностью перерисовалось. Нет?

    2. Если я создаю контекст в памяти с помощью "CreateCompatibleDC", его по окончании нужно "ReleaseDC" или "DeleteDC"? Я-то всю жизнь делал второе, а надысь в одном исходнике увидел первое....
     
  2. asd

    asd New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2005
    Сообщения:
    952
    Адрес:
    Russia
  3. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    da-007
    Если правильно установить цвета, координаты и грамотно создать DC, DrawText прекрасно отработает, не смотря на то, что DC в памяти. В вашем коде где-то есть ошибка.

    Да, этот метод чреват мерцанием.

    Не полностью одинаковые (см. описание), но оба действительно говорят винде, что продолжать слать WM_PAINT уже не надо до следующего обновления.

    Надо хоть иногда в msdn заглядывать!
     
  4. tmp_name_0001

    tmp_name_0001 New Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    85
    Вот это точно подойдёт
     
  5. da-007

    da-007 New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    13
    Всем огромное спасибо, помогли. Без стеба.

    Quantum:
    "грамотно создать DC, DrawText прекрасно отработает"

    DrawText - работает. А вот TextOut - не хочет =( В принципе, разницы для меня нет, тока я изначально именно с TextOut работал =)

    "Надо хоть иногда в msdn заглядывать!"

    Обижаете =) Я ж все правильно делал... Именно сомнение у меня появилось, глядя на чужие исходники =)
     
  6. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    da-007
    Значит, где-то всё-таки есть ошибка. Можете выложить фрагмент кода.

    msdn внушает больше доверия, чем исходник Васи Пупкина.
     
  7. da-007

    da-007 New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    13
    Все, сдаюсь. Я вообще ничего не понимаю; объясните, плз, идиоту. Задача: вывести текст на окно с картинкой, используя прозрачный фон для текста.

    Если не сложно, загляните в ветку http://www.wasm.ru/forum/viewtopic.php?id=16291

    Итого, результаты: код работает. Но как он работает, и почему - мне непонятно. Понятно лишь одно: все, что я написал - извращение.

    Язык С-- (гибрид Си и ассемблера), комменты вроде расставил... Cимвол "#" - это... смещение, адрес переменной, на ассемблере это "@". Проверки на ошибки убрал для удобочитаемости, в оригинале они есть, ошибок при выполнении не возникает.

    Создание дочернего окна:

    Код (Text):
    1. // -----------------------------------------------------------
    2. WndClassEx.cbSize=sizeof(WndClassEx);
    3. WndClassEx.hInstance=hInst;
    4. WndClassEx.style=CS_HREDRAW|CS_VREDRAW;
    5. WndClassEx.lpfnWndProc=#WndProcTextClass;
    6. WndClassEx.cbWndExtra=0;
    7. WndClassEx.cbClsExtra=0;
    8. WndClassEx.hIcon=NULL;
    9. WndClassEx.hCursor=LoadCursor(0,IDC_ARROW);
    10. WndClassEx.hbrBackground=NULL;
    11. WndClassEx.lpszMenuName=0;
    12. WndClassEx.lpszClassName="My_Text";
    13. WndClassEx.hIconSm=NULL;
    14. RegisterClassExA (#WndClassEx);
    15.  
    16. hWndCpuInfo=CreateWindowEx (0,"My_Text",NULL,WS_CHILD|WS_VISIBLE,100,100,SIZE_X,SIZE_Y,hWndMain,NULL,hInst,NULL);
    17. // -----------------------------------------------------------
    18.  
    19. Обработчик WM_PAINT:
    20. // -----------------------------------------------------------
    21. void RepaintCpuInfo ()
    22. {
    23. dword hDC, hMemDC;
    24. RECT  Rect;          
    25. dword hBmp;    
    26.  
    27. // Cообщим винде что успешно отрисовались
    28. ValidateRect (hWndCpuInfo,false);
    29.  
    30. // Получим контекст окошка, создадим временный контекст
    31. hDC=GetDC (hWndCpuInfo);
    32. hMemDC=CreateCompatibleDC(EAX);
    33.  
    34. // Создадим битмап фона этой картинки
    35. hBmp=CreateBitmap (SIZE_X,SIZE_Y,1,32,#PsetCpuInfoBackground);
    36.  
    37. // Назначить фоновую картинку нашему контексту (НАХРЕНА??)
    38. SelectObject (hMemDC,EAX);
    39.  
    40. // Рисуем буковоки
    41. SelectObject (hMemDC,hFont);
    42. SetBkMode (hMemDC,TRANSPARENT);
    43. SetTextColor (hMemDC,0x101010);
    44. Rect.top=0; Rect.right=SIZE_X; Rect.left=0; Rect.bottom=SIZE_Y;
    45. DrawText (hMemDC, #CpuUsageA, -1, #Rect, DT_RIGHT);
    46.  
    47. // Скопировать содержимое контекста
    48. BitBlt (hDC,0,0,SIZE_X,SIZE_Y,hMemDC,0,0,SRCCOPY);
    49.  
    50. // Освободить контексты, все в порядке
    51. ReleaseDC (hWndCpuInfo,hDC);
    52. DeleteDC (hMemDC);
    53. DeleteObject (hBmp);
    54. }
    55. // -----------------------------------------------------------
    Вопрос: нафига мне делать "SelectObject (hMemDC,EAX);" ("назначать" картинку контексту в памяти)? Если следующей же строчкой выбирается другой объект? Т.е. по идее, эта строчка ничего не меняет. Однако без нее ничего не работает. Кстати говоря, если думать дальше, то и CreateBitmap - не нужен... Да! Если вынести CreateBitmap в блок инициализации - тоже ни фига не работает: контекст не очищается.

    И по ходу - еще вопрос: SelectObject, как я понимаю, возвращает хендл предудущего выбранного объекта (П.В.О.), и перед удалением контекста надо выбрать обратно этот самый П.В.О. Вопрос: это обязательно?

    И в догонку - я так понимаю, можно вообще обойтись без CreateBitmap, а использовать "LBS.lbStyle=BS_HOLLOW" - "CreateBrushIndirect" - "FillRect (hMemDC....", но так у меня ничего не получилось. Ясное осознание того, что я изобретаю велосипед :dntknw:
     
  8. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Объект объекту рознь :)
    HFONT != HBITMAP.
    Нет. Ты же всё равно удаляешь DC.
    В каком таком блоке инициализации? WM_CREATE?
     
  9. da-007

    da-007 New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2006
    Сообщения:
    13
    Дык это понятно, но я же не произвожу никаких действий с выбранным объектом?

    Нет, в ф-ии main, после создания главного и дочерних окон. Но я так понимаю, там затычка в другом: в связке "Select object" - "DrawText" - DrawText "портит" картинку фона... Но причины этого мне не понятны...
     
  10. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    То есть?
    При выборе Bitmap копируется в контекст.
     
  11. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    n0name
    Отображается! "Копируется" - это через BitBlt.

    Не согласен. В msdn написано, что DeleteDC "deletes the specified device context" и всё. Там не написано "releases the selected objects". Поэтому, даже если код работает и утечек ресурсов не наблюдается, не факт, что в следующих версиях винды не полезут глюки во всех ваших программах. Лучше лишний раз вызвать SelectObject.

    da-007
    Мне не совсем понятен смысл фразы "контекст не очищается".

    Размер кистей ограничен. Поэтому не любой битмап может стать кистью. Даже если Ваш битмап помещается в кисть, нужно ещё вызывать SetBrushOrgEx, чтобы картинку не "перекашивало".
     
  12. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Угу, с терминологией у меня туго :)
    Как я понял вопрос не в этом, а нужно ли выбирать исходный объект.
     
  13. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/devcons_5g83.asp

    Здесь ^^^ сказано, что DeleteObject() возвратит ошибку, если GDI объект находится в HDC. Так что лучше не рисковать и всё-таки "выбрать" его назад.