проблема с битмапом

Тема в разделе "WASM.WIN32", создана пользователем DPX, 15 июн 2005.

  1. DPX

    DPX New Member

    Публикаций:
    0
    Регистрация:
    13 фев 2005
    Сообщения:
    47
    Адрес:
    Russia
    Приветствую!

    Делаю трейнер на АSM, и мне понадобилось отобразить битмап. Прочитал урок Iczelion`а, сделал, как там написано:



    .asm:
    Код (Text):
    1.  
    2. IDB_BACK equ 666
    3. ...
    4. DlgProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
    5.       LOCAL ps:PAINTSTRUCT
    6.       LOCAL hdc:HDC
    7.       LOCAL hMemDC:HDC
    8.     mov     eax,uMsg
    9.     .if eax==WM_CREATE
    10.         invoke LoadBitmap,hInstance,IDB_BACK
    11.         mov hBackground, eax
    12.     .elseif eax==WM_PAINT
    13.                 invoke BeginPaint,hWin,addr ps
    14.                 mov    hdc,eax
    15.                 invoke CreateCompatibleDC,hdc
    16.                 mov    hMemDC,eax
    17.                 invoke SelectObject,hMemDC,hBackground
    18.                 invoke BitBlt,hdc,0,12,244,57,hMemDC,0,0,SRCCOPY
    19.                 invoke DeleteDC,hMemDC
    20.                 invoke EndPaint,hWin,addr ps           
    21.     .elseif eax==WM_COMMAND
    22.             mov eax, wParam
    23.             mov edx, wParam
    24.             .if lParam==0
    25.             .else  
    26.                 shr edx, 16
    27.                 .IF dx==BN_CLICKED
    28.                     .if ax==ID_QUIT
    29.                         invoke EndDialog,hWin,0
    30.                     .endif
    31.                 .endif
    32.             .endif     
    33.     .elseif eax==WM_CLOSE
    34.                 invoke DeleteObject,hBackground
    35.         invoke EndDialog,hWin,0
    36.     .else
    37.         mov     eax,FALSE
    38.         ret
    39.     .endif
    40.     mov     eax,TRUE
    41.     ret
    42.  
    43. DlgProc endp




    .rc:
    Код (Text):
    1. #define IDB_BACK 666
    2. IDB_BACK BITMAP "back.bmp"




    всё компилируется, но при запуске битмапа нет! Может, подскажете, что делать?
     
  2. alpet

    alpet Александр

    Публикаций:
    0
    Регистрация:
    21 сен 2004
    Сообщения:
    1.221
    Адрес:
    Russia
    Отладчиком проверь - действительно ли загружается сам битмап. Похоже что сообщение WM_CREATE в данной программе заменяется WM_INITDIALOG, проверить это тоже не мешает.
     
  3. n0p

    n0p 10010000b

    Публикаций:
    0
    Регистрация:
    7 май 2003
    Сообщения:
    256
    Адрес:
    Новосиbeerск
    Да, очень похоже на то, что WM_CREATE надо на WM_INITDIALOG заменить.



    Кроме того, в целях оптимизации можно вынести CreateCompatibleDC в WM_INITDIALOG для облегчения процедуры прорисовки. Зачем его создавать каждый раз, а потом удалять?
     
  4. NoName

    NoName New Member

    Публикаций:
    0
    Регистрация:
    1 авг 2004
    Сообщения:
    1.229
    У диалоговых окон WM_INITDIALOG вместо WM_CREATE.
     
  5. alpet

    alpet Александр

    Публикаций:
    0
    Регистрация:
    21 сен 2004
    Сообщения:
    1.221
    Адрес:
    Russia
    n0p

    На счет оптимизации, похоже что в этом случае как раз все правильно, и ничего оптимизировать не надо. Сообщение прорисовки в зависимости от условий выполнения программы будет приходить не очень часто (обработка WM_PAINT мало оказывает влияние на производительность проги в целом), тогда как дескрипторы GDI всегда лучше экономить (по крайней мере так всеръез утверждается в MSDN). Другое дело скажем кисти - для сообщения WM_CTLCOLORDLG, их действительно лучше выделять при инициации диалога.
     
  6. n0p

    n0p 10010000b

    Публикаций:
    0
    Регистрация:
    7 май 2003
    Сообщения:
    256
    Адрес:
    Новосиbeerск
    alpet

    Пожертвовать одним дескриптором ради снижения нагрузки на систему кажется мне разумным. Конечно, если перерисовка происходит не очень часто (хотя даже в состоянии покоя окна это иногда происходит), это не так страшно, а если еще и прога часто обработчик вызывает?
     
  7. alpet

    alpet Александр

    Публикаций:
    0
    Регистрация:
    21 сен 2004
    Сообщения:
    1.221
    Адрес:
    Russia
    n0p

    Конечно если регулярность высока - скажем график анимированный рисуется можно и не запрашивать контексты каждый раз. Другое дело что у Windows для большинства окон их всегда находится достаточном количестве готовых для получения - сама операция CreateCompatibleDC возможно выполняется только в пределах USERмода и много времени не занимает. Для трейнера сомнительно что будет использоваться анимированная графика и вообще требования к его производительности не велики. Получать ресурсы по необходимости, и освобождать их когда они больше не нужны (вместо содержания нескольких глобальных переменных) в конечном счете лишь стиль программирования, имеющий больше отношение к надежности и простоте кода, чем к его производительности, и конечно он наиболее применим в крупных программах.
     
  8. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    К слову: а где SelectObject() перед DeleteDC()?



    Из MSDN: "An application should always replace a new object with the original, default object after it has finished drawing with the new object."
     
  9. n0p

    n0p 10010000b

    Публикаций:
    0
    Регистрация:
    7 май 2003
    Сообщения:
    256
    Адрес:
    Новосиbeerск
    alpet

    Ну, в принципе, согласен.
     
  10. DPX

    DPX New Member

    Публикаций:
    0
    Регистрация:
    13 фев 2005
    Сообщения:
    47
    Адрес:
    Russia
    насчёт WM_INITDIALOG:

    поменял, и всё заработало! Спасибо!
     
  11. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    DPX



    Неплохо тему раздули :)



    AsmGuru62







    should не must :derisive:
     
  12. Turkish

    Turkish New Member

    Публикаций:
    0
    Регистрация:
    25 окт 2004
    Сообщения:
    80
    Адрес:
    Russia
    Мои 5 копеек. Зачем восстанавливать исходное состояние объекта перед его удалением? Все равно что вызывать CloseHandle перед ExitProcess.

    Если контекст в памяти будет удален, то будет удалены все связи с другими объектами.

    Вообще не надо строго вымолнять инструкции Microsofta, Iczeliona и прочих личностей.
     
  13. n0p

    n0p 10010000b

    Публикаций:
    0
    Регистрация:
    7 май 2003
    Сообщения:
    256
    Адрес:
    Новосиbeerск
    Turkish

    В некоторых случаях это необходимо. Что если после удаления объекта процесс рисования не завершается? Тогда при обращении к удаленному объекту может случится все что угодно. Вот для таких случаев и надо предусматривать восстановление.
     
  14. Quantum

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

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    Turkish



    И чтоб это проверить надо каждый раз лезть в ядро? Да ещё и на всех версиях винды? Увольте! Я лучше лишний раз SelectObject вызову лишь бы этот GDI-объект ко мне в кошмарных снах не являлся.





    Хоть бы смайлик дописали, а то новички могут за чистую монету принять :)
     
  15. alpet

    alpet Александр

    Публикаций:
    0
    Регистрация:
    21 сен 2004
    Сообщения:
    1.221
    Адрес:
    Russia
    Контекст устройства, помимо прочего является структурой GDI, описывающей свойства и аттрибуты рисования, и по разному связанную с другими. Как правило свежим контекстам назначаются общие для программ перья и кисти (BLACK_PEN, WHITE_BRUSH), которые можно также получать с помощью GetStockObject (...). Так что систему дефакто не волнует с чем связан контекст, когда приложение решило от него отделаться с помощью ReleaseDC/DeleteDC. Это к примеру показано в MSND примере "Capturing an Image" - там результат работы функции SelectObject используется лишь для проверки, была ли ошибка.



    И раз тут все равно задета проблема растров, такой вот вопрос: как правильно и полностью (как PrintScreen) скопировать текущий декстоп со всеми окнами на нем в системах Win2k/XP?
     
  16. alpet

    alpet Александр

    Публикаций:
    0
    Регистрация:
    21 сен 2004
    Сообщения:
    1.221
    Адрес:
    Russia
    Похоже способ неизвестен. Стандартный прием BitBlt то MemoryDC к сожалению не помогает - полупрозрачные окна в скриншоте не отрисовываются.