? про прсостейшую отрисовку с 2й буферизацией

Тема в разделе "WASM.BEGINNERS", создана пользователем Romm, 18 янв 2009.

  1. Romm

    Romm New Member

    Публикаций:
    0
    Регистрация:
    24 авг 2007
    Сообщения:
    12
    собсно вопрос прост - сабж. если точнее то хотел бы видеть те части функции диалога которые отрабатывают создание буффера и на сообщение WM_PAINT.
    Например то, что при создании окна, указав флаги VREDRAW и HREDRAW я получу некоторые глюки - это я нигде не нашел (точнее не придумал такого запроса в поисковик).
    Только тут проблема - при ресайзе картинка не мигает, но зато и ведет себя немного не так.
    А вот че делать при WM_PAINT я вобщем... даже не догадываюсь.
    код не привожу - слишком я в нем неуверен...
    в идеале хотел бы видеть чтонибудь простое - ф-ю диалога с отрисовкой хотяб одной линии с помощью LineTo(Ex), чтоб не мигала и был нормальный ресайз(при котором линия перемещается по окошку). Понимаю запрос конечно нескромный, но я почти сделал то прошу, в не сильно большом обьеме текста. единственный касяк - линия оставляла артефакты при ресайзе - и я и так бился и этак и хоть бы что!
    Вобщем ЛЮДИ ПОМОЖИТЕ ПЛИЗ МНЕ ДУРАКУ.
     
  2. Partner

    Partner Павел

    Публикаций:
    0
    Регистрация:
    28 фев 2008
    Сообщения:
    917
    Адрес:
    Los Angeles
    erase background ?
     
  3. Arthur

    Arthur New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2007
    Сообщения:
    494
    Что есть двойная буферизация? Это когда рисуешь не на экран а куда нибудь в память, а потом уже то что нарисовал передаешь на экран ( в данном случае на окно ). Так вот вам нужно создать HDC, на нем рисовать а потом с помощью BitBlt, передать с HDC (памяти) в HDC (окна).

    А вообще посмотрите в раздел WASM.WIN32, там вроде эта тема поднималась.
     
  4. Romm

    Romm New Member

    Публикаций:
    0
    Регистрация:
    24 авг 2007
    Сообщения:
    12
    неа. помойму не то. я хотел видеть через CreateCompatibleDC. хотя я призадумался - а не надо ли очистить окошко перед выводом? хотя с другой стороны линия при ресайзе просто гонит, не оставляя предыдущего "кадра"
     
  5. Romm

    Romm New Member

    Публикаций:
    0
    Регистрация:
    24 авг 2007
    Сообщения:
    12
    2артур: да парень ты мне помог))) всмысле оправдываться на глупый вопрос меньше текста писать - это тот ответ который выдают поисковики.
    А вобще создать буфер я вроде как могу (неуверен ток правильно ли). вопрос начинает становиться на WM_PAINT - при ресайзе че делать? я ж при ресайзе вроде как получу и WM_PAINT? или нет? или надо DleteDC\RelaseDC прям в WM_SIZE?
     
  6. Romm

    Romm New Member

    Публикаций:
    0
    Регистрация:
    24 авг 2007
    Сообщения:
    12
    незабывайте это раздел для новичков. дата регистрации не отменяет этого звания. ВАЛЕНОК(пока еще). времени мало блин. и еще - еси не отвечаю - это не значит что я забил на это дело: может $ на инете кончились, мож еще чо случилось. всем кто ответит по делу и без понтов - спасибки заранее, даже если просто попытался достучаться до моего моска.
     
  7. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    Romm
    Arthur всё правильно пишет. Ресайз делается ЕМНИП при помощи StretchBlt автоматически.
     
  8. Arthur

    Arthur New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2007
    Сообщения:
    494
    Romm

    Код (Text):
    1.   HDC bufferDC;
    2.   HBITMAP bufferBMP;
    3.  
    4.   void createBuffer(HWND wnd)
    5.   {
    6.      HDC dc;
    7.      RECT rc;
    8.      
    9.      dc = GetDC(wnd);
    10.      GetClientRect(wnd, &rc);
    11.      bufferDC = CreateCompatibleDC(dc);
    12.      bufferBMP = CreateCompatibleBitmap(dc, rc.right, rc.bottom);
    13.      ReleaseDC(wnd, dc);
    14.      SelectObject(bufferDC, bufferBMP);
    15.   }
    16.  
    17.   void deleteBuffer()
    18.   {
    19.     DeleteObject(bufferBMP);
    20.     DeleteDC(bufferDC);
    21.   }
    22.  
    23.   LRESULT CALLBACK WinProc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
    24.   {
    25.     switch(msg)
    26.     {
    27.       case WM_SIZE:
    28.         RedrawWindow (hwnd, 0, 0, RDW_INVALIDATE);
    29.         break;
    30.       case WM_PAINT:
    31.       {
    32.         PAINTSTRUCT ps;
    33.         HDC wdc;
    34.         RECT rc;
    35.         GetClientRect(hwnd, &rc);
    36.         FillRect(bufferDC, &rc, (HBRUSH)COLOR_WINDOW);
    37.         wdc = BeginPaint(hwnd, &ps);
    38.         BitBlt(wdc, 0, 0, rc.right, rc.bottom, bufferDC, 0, 0, SRCCOPY);
    39.         EndPaint(hwnd, &ps);
    40.         break;
    41.       }
    42.       ...
    43.     }
    44.   }
    вроде так.
     
  9. Romm

    Romm New Member

    Публикаций:
    0
    Регистрация:
    24 авг 2007
    Сообщения:
    12
    Arthur
    ща проверять буду. отрисовку линии добавлю, с её движением при ресайзе. и вот там уже и покажешь где касяк, ок?
     
  10. Arthur

    Arthur New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2007
    Сообщения:
    494
    Romm
    Пробуй, пока я в интернете :)

    поправка:
    Код (Text):
    1.   ReleaseDC(dc);
    2.   заменить на
    3.   ReleaseDC(wnd, dc);
     
  11. Arthur

    Arthur New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2007
    Сообщения:
    494
    Еще пару поправок (гы, вот что значить писать по памяти :))

    Код (Text):
    1. void createBuffer(HWND wnd)
    2. {
    3.    HDC dc;
    4.    RECT rc;
    5.  
    6.    dc = GetDC(wnd); // добавить эту строку
    7.    ...
    8. }
    и последний параметр BitBlt, не PATCOPY, а SRCCOPY.

    вобщем сейчас исправлю свой пост.
     
  12. Romm

    Romm New Member

    Публикаций:
    0
    Регистрация:
    24 авг 2007
    Сообщения:
    12
    Arthur
    ну эт я в курсе. кста я рисую на диалоге - вроде не матюкается
     
  13. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    Arthur
    Раз уж ты используешь GetDC, то убери BeginPaint, а EndPaint замени на ValidateRect.

    Вроде-бы вместо BitBlt надо StretchBlt юзать (чтобы ресайз был).
     
  14. Arthur

    Arthur New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2007
    Сообщения:
    494
    murder
    GetDC нужен только для того что бы создать совместимый контекст и битмап. Так что смотрите далее, я освобождаю его.

    Можно применять BitBlt если битмап буфера по размерам идентичен окну.
     
  15. Romm

    Romm New Member

    Публикаций:
    0
    Регистрация:
    24 авг 2007
    Сообщения:
    12
    не, мне при ресайзе никакой картинки не надо(про обязателность CreateComBitmap я знаю)
    мне надо чтоб при ресайзе линия двигалась вслед за ПРАВОЙ рамкой окна. никакого фона не надо. белая линия на черном фоне.
     
  16. Romm

    Romm New Member

    Публикаций:
    0
    Регистрация:
    24 авг 2007
    Сообщения:
    12
    времени как всегда))) и $ тоже))) щас инет кончится
    вобщем остановился пока тут:
    (отрисовывает без мигания, но че делать при ресайзе не пойму никак - вроде гдето читал что BeginPaint действует ток в контексте обработки WM_PAINT, это верно?)
    Код (Text):
    1. .ELSEIF eax==WM_PAINT
    2.         invoke GetClientRect,hwnd,addr rect
    3.         invoke BeginPaint,hwnd,addr ps
    4.         mov hwdc,eax
    5.        
    6.         mov hcdc,f(CreateCompatibleDC,hwdc)
    7.         mov hbo,f(CreateCompatibleBitmap,hcdc,rect.right,rect.bottom)
    8.         invoke SelectObject,hcdc,hbo
    9.        
    10.         invoke GetStockObject,WHITE_PEN
    11.         invoke SelectObject,hcdc,eax
    12.         invoke MoveToEx,hcdc,30,30,0
    13.         invoke LineTo,hcdc,100,100
    14.        
    15.         invoke BitBlt,hwdc,0,0,rect.right,rect.bottom,hcdc,0,0,SRCCOPY
    16.        
    17.        
    18.         invoke EndPaint,hwnd,addr ps
    НО! мне надо через GetDC, и к томуже с движением линии вместе с правой рамкой окна.
    У тебя там создание буффера в отдельной функции, и возникает вопрос - rect окна ты находиш там, а при ресайзе он меняется; надо включить DeleteBuff/затем/CreateBuff в WM_SIZE? ну и кроме того отрисовку ты делаеш всеже через beginpaint - это вроде не обязательно, поэтому я и хочу через GetDC - правда, не придется ли мне самому метить регион, чтоб в процессе BitBilt не получить WM_PAINT&
     
  17. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    что-то я тут не увидел функции InvalidateRect(HWND, 0, 0). Поставь в конце Resize и будет все обновляться
     
  18. _basmp_

    _basmp_ New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2005
    Сообщения:
    2.939
    чтоб не блымало и небыло артефактов в большинстве случаев достаточно рисовать по WM_ERASEBKGND. Вызывается, когда по WM_PAINT вызывается бегинпэйнт
     
  19. Romm

    Romm New Member

    Публикаций:
    0
    Регистрация:
    24 авг 2007
    Сообщения:
    12
    да, спс про ValidateRect. я правда уже сам нашел к тому времени - BeginPaint сбрасывает недействительный регион, а если я отрабатываю WM_PAINT без ValidateRect, то сообщение WM_PAINT отсылается постоянно. про ERASEBACKGND - я рисую при WM_PAINT, в бэкграунде просто возвращаю 1 - этого уже достаточно. кстати про BeginPaint написано, что там в структуре есть fErase: флаг стирания бэкграунда, ставил в 0 чтобы не получать WM_ERASEBKGND, но чет ниче не вышло.
    У меня возник вопрос - фон. он рассматривается как отдельный "обьект" при отрисовке? т.е. я смогу заменить фон, не меняя основной картинки к-ю рисую в вм_паинт? или нет? просто если да, то это приобретает смысл, и рисование в WM_ERASEBKGND - лишние накладные расходы при попытке просто изменить фон не меняя картинки; если нет то нафиг тагда вм_паинт?
    я щас пока тут:
    Код (Text):
    1. .ELSEIF eax==WM_PAINT
    2.         invoke GetClientRect,hwnd,addr rect1
    3.         invoke ValidateRect,hwnd,addr rect1     ;сбрасывает ВСЁ ОКНО! на всяк случай полностью
    4.         mov hWindowDC,f(GetDC,hwnd)
    5.         ;  invoke BeginPaint,hwnd,addr ps       ;сбрасывает НЕДЕЙСТВИТЕЛЬНЫЙ rect!
    6.         ;  mov hWindowDC,eax
    7.        
    8.         mov hCompatibleDC,f(CreateCompatibleDC,eax)
    9.         mov hCompatibleBitmap,f(CreateCompatibleBitmap,hWindowDC,rect1.right,rect1.bottom)
    10.         invoke SelectObject,hCompatibleDC,eax
    11.        
    12.        
    13.         invoke GetStockObject,WHITE_BRUSH
    14.         invoke FillRect,hCompatibleDC,addr rect1,eax
    15.        
    16.         invoke GetStockObject,BLACK_PEN
    17.         invoke SelectObject,hCompatibleDC,eax
    18.         invoke MoveToEx,hCompatibleDC,line.left,line.top,0
    19.         invoke LineTo,hCompatibleDC,line.right,line.bottom
    20.        
    21.         invoke BitBlt,hWindowDC,0,0,rect1.right,rect1.bottom,hCompatibleDC,0,0,SRCCOPY
    22.        
    23.         invoke DeleteObject,hCompatibleBitmap
    24.         invoke DeleteDC,hCompatibleDC
    25.         invoke ReleaseDC,hwnd,hWindowDC
    26.        
    27.     .ELSEIF eax==WM_SIZE
    28.         ;вычисляем сдвиг линии
    кстати возможен вариант как без вычисления обновляемого прямоугольника, так и с ним - я могу обновлять просто все окно целиком, нафига мне заморачиватся еще и с регионами? дает ли 2й вариант ЗНАЧИТЕЛЬНЫЙ выигрыш в скорости при например редакторе текста?
    подозреваю мне щас начнут говорить что редактор текста это не для новичков. я знаю. но мне интересней учиться на реалистичных примерах. да и не собираюсь я делать суперский редактор с учетом кернинга и межстрочного интервала. так что не надо иронии - у меня её у самого хватает.
     
  20. _basmp_

    _basmp_ New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2005
    Сообщения:
    2.939
    Romm
    вм_пайнт рисует в инвалидированом регионе, вм_ерасе.. по всему клиенту (окну?). вм_ерасе.. посылается из бегин пайнт, хдц вы получаете в впарам.

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