двойная буферизация(

Тема в разделе "WASM.BEGINNERS", создана пользователем sometime, 25 июн 2009.

  1. sometime

    sometime Odessa

    Публикаций:
    0
    Регистрация:
    22 апр 2009
    Сообщения:
    227
    Адрес:
    sunday
    что уже не делал - все равно при перетаскивании окна блики по краям окна((
    мож кто подскажет где я мог ошибится,точнее где я ошибся)
    вот один вариант как я делал:
    Код (Text):
    1. hdc = BeginPaint( hWnd, &ps );  
    2.                 HDC memDC;
    3.                 memDC = CreateCompatibleDC(hdc);
    4.                 HBITMAP bmp_, oldBit;
    5.                 bmp_ = CreateCompatibleBitmap(hdc, 400, 500);
    6.                 oldBit = (HBITMAP)SelectObject(memDC, bmp_);
    7.                 BitBlt(hdc, 0, 0, 400, 500, memDC, 0, 0, SRCCOPY);
    8.                 SelectObject(memDC, oldBit);
    9.                 EndPaint(hWnd, &ps);
    10.                 //DeleteObject( memBit );
    11.                 DeleteObject( oldBit );
    12.                 DeleteObject( memDC );*/
    В bmp_ как я понял должен находится мой картинка - пока не гружу её, НО мое черное окошко продолжает мирцать при перетаскивании...поискал на васме,нашел вариант с прорисовкой линии - решил просто переписать и если глюков с окном не будет - переделать с линии на битмап. Вот ссылка http://www.wasm.ru/forum/viewtopic.php?id=30757
    а вот то как я это в ++ переделал:
    Код (Text):
    1.                     RECT rect;
    2.                 GetClientRect( hWnd, &rect );
    3.                 ValidateRect( hWnd, &rect );
    4.                     HDC hWindowDC, hCompatibleDC;
    5.                 hWindowDC = GetDC( hWnd );
    6.                 hCompatibleDC = CreateCompatibleDC( hWindowDC );
    7.                     HBITMAP hCompatibleBitmap;
    8.                 hCompatibleBitmap = CreateCompatibleBitmap( hWindowDC, rect.right, rect.bottom );
    9.                 SelectObject( hCompatibleDC, hCompatibleBitmap );
    10.                 FillRect( hCompatibleDC, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH) );
    11.                 SelectObject( hCompatibleDC, GetStockObject(BLACK_BRUSH) );
    12.                 MoveToEx( hCompatibleDC, 10, 10, 0 );
    13.                 LineTo( hCompatibleDC, 100, 100 );
    14.                 BitBlt( hWindowDC, 0, 0, rect.right, rect.bottom, hCompatibleDC, 0, 0, SRCCOPY );
    15.                 DeleteObject( hCompatibleBitmap );
    16.                 DeleteDC( hCompatibleDC );
    17.                 ReleaseDC( hWnd, hWindowDC );
    всё тоже - мирцает сабака при перетаскивании(

    чё не так - подскажите плз....
     
  2. sometime

    sometime Odessa

    Публикаций:
    0
    Регистрация:
    22 апр 2009
    Сообщения:
    227
    Адрес:
    sunday
    вот выган получился - 3-й день парюсь - ПОЧЕМУ??? - да потому.....что комп тупит) или так должно быть, не знаю)) - карочь и каспер и остальные выдают тотже глюк.)
    Теперь вопрос - а каким методом лучше всего выводить битмап на окно?
    1,2 или вот таким:
    Код (Text):
    1. case WM_CREATE:
    2.             hDC = GetDC( hWnd );
    3.             bmFull = CreateCompatibleBitmap( hDC, 400, 500 );
    4.             hScrDC = CreateCompatibleDC( hDC );
    5.             SelectObject( hScrDC, bmFull );
    6.             hMemDC = CreateCompatibleDC( hDC );
    7.             SelectObject( hMemDC, bmFrame );
    8.             BitBlt( hScrDC, 0, 0, 400, 500, hMemDC, 0, 0, SRCCOPY );
    9.  
    10.             DeleteDC( hMemDC );
    11.             DeleteObject( bmFrame );
    12.             ReleaseDC( hWnd, hDC );
    13.  
    14. case WM_PAINT:
    15.                 BeginPaint( hWnd, &ps );
    16.                 BitBlt( hDC, 0, 0, 400, 500, hScrDC, 0, 0, SRCCOPY );
    17.                 EndPaint( hWnd, &ps );
    только вот пока не пойму - третий вариант получился так что если запустить прогу и развернуть,например блокнот - он затирает её часть где они пересекнулись) Но когда я окно свое вытащу за пределы экрана и затащу обратно - все гуд,картинка возобновляется)
    чё за ...???
     
  3. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    sometime
    > мирцает
    Покажи обработчик WM_ERASEBKGND.
     
  4. sometime

    sometime Odessa

    Публикаций:
    0
    Регистрация:
    22 апр 2009
    Сообщения:
    227
    Адрес:
    sunday
    return TRUE;

    -эт я уже тож вычитал).

    уже все переделал опять(( ща выглядет вот так:
    Код (Text):
    1.         case WM_CREATE:
    2.             HDC hMemDC;
    3.             HBITMAP bmFull, bmFrame;
    4.  
    5.             MyImg = LoadResources( GetModuleHandle( 0 ), NULL );
    6.             reinterpret_cast<Gdiplus::Bitmap*>(MyImg)->GetHBITMAP(Gdiplus::Color(0,0,0), &bmFrame);
    7.  
    8.             hDC = GetDC( hWnd );
    9.             hScrDC = CreateCompatibleDC( hDC );
    10.             SelectObject( hScrDC, bmFrame );
    11.             ReleaseDC( hWnd, hDC );
    12.             DeleteObject( bmFrame );
    13.  
    14.         case WM_PAINT:
    15.                 BeginPaint( hWnd, &ps );
    16.                 BitBlt( hDC, 0, 0, 400, 500, hScrDC, 0, 0, SRCCOPY );
    17.                 EndPaint( hWnd, &ps );
    18.  
    19.         case WM_ERASEBKGND:
    20.                                return TRUE; // вот если так - рисует заглючно окошко
    21.                                                  // а если закоментить - ресурсы(память поглащает страшно)
    и причём заметил -- если при WM_ERASEBKGND - возвращать тру,то сообщение WM_CREATE - постоянно просится на обработку).

    с тем что ща память паглащает - ща буду сматреть какраз, но а вобщем - подскажите мож чего полезного на эту тему.
     
  5. sometime

    sometime Odessa

    Публикаций:
    0
    Регистрация:
    22 апр 2009
    Сообщения:
    227
    Адрес:
    sunday
    заработало) - но вот вопрос такой - почему прога жрёт в памяти 7Мб - там ничего нету,картинка на пару кб((
    код прежний,только вот
    Код (Text):
    1.                         case WM_PAINT:
    2.                 hdc = BeginPaint( hWnd, &ps );
    3.                 BitBlt( hdc, 0, 0, 400, 500, hScrDC, 0, 0, SRCCOPY );
    4.                 EndPaint( hWnd, &ps )
    изменил... А по поводу return TRUE и ERASE_BACKGROUND - брейк случайно закоментил с остальным)

    но всеже - подскажите как правильно делать!!! - вариантов куча и сам чё не все полностью понимаю,пока) - узнаю как лучше и надесь пойму почему.
     
  6. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    мерцание происходит от того, что у тебя окно либо сначала полностью стирается потом полностью отрисовывается, либо если отрисовывается довольно большая часть окна, для этого стоит включить двойную буферизацию окна (встроенную в винду)
    Код (Text):
    1. PIXELFORMATDESCRIPTOR.dwFalgs=PFD_DOUBLEBUFFER;
    2. index=ChoosePixelFormat(hdc, PIXELFORMATDESCRIPTOR);
    3. SetPixelFormat(hdc, index, PIXELFORMATDESCRIPTOR);
    вот примерно так
     
  7. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.912
    sometime
    Если просто требуется вывести картинку на экран, то можно обойтись без всяких BeginPaint, EndPaint, BitBlt, CreateCompatibleDC и т.д. -- смотри, как это делается во вложении (сорц, ехе и картинка) пример того как можно сделать 25 урок Iszelion'a минимальными средствами сам экзешник -- 595 байт на диске, в памяти 2672 Кб.
    Написано на nasmw без линкера и компилятора ресурсов.
     
  8. sometime

    sometime Odessa

    Публикаций:
    0
    Регистрация:
    22 апр 2009
    Сообщения:
    227
    Адрес:
    sunday
    спасибо! посмотрю как у тебя там все происходит,но пишу на VC++ . с радостью писал бы на асме,но нужно на С++ к сожалению((
    То что я написал - темповский прожект - на моем компе с ХР(СП3_зверь) - хавает 5.8(вчера нашел куда метр подевался-лишние ресурсы)) ,а на другом компе где стоит 7-ка всего ничего 1.8 метра.....что за бред пока не пойму,но кажется мне что винда у меня чёт плохо стоит - там есть свои еще глюки)
    На 7-ке работает все прекрасно ни глюков, ни юликов, ни памяти много) - Windows_
    Мож кто подскажет где может сабака зарыта быть с той памятью?
     
  9. sometime

    sometime Odessa

    Публикаций:
    0
    Регистрация:
    22 апр 2009
    Сообщения:
    227
    Адрес:
    sunday
    да кстати вот сам код:
    Код (Text):
    1.         case WM_CREATE:
    2.             HDC hMemDC;
    3.             HBITMAP bmFull, bmFrame;
    4.  
    5.             MyImg = LoadResources( GetModuleHandle( 0 ), NULL );
    6.             reinterpret_cast<Gdiplus::Bitmap*>(MyImg)->GetHBITMAP(Gdiplus::Color(0,0,0), &bmFrame);
    7.  
    8.             hdc = GetDC( hWnd );
    9.             hScrDC = CreateCompatibleDC( hdc );
    10.             SelectObject( hScrDC, bmFrame );
    11.             ReleaseDC( hWnd, hdc );
    12.             DeleteObject( bmFrame );
    13.             DeleteObject( MyImg );
    14.  
    15.         case WM_PAINT:
    16.                 hdc = BeginPaint( hWnd, &ps );
    17.                 BitBlt( hdc, 0, 0, 400, 500, hScrDC, 0, 0, SRCCOPY );
    18.                 EndPaint( hWnd, &ps );
    19.  
    20.         case WM_ERASEBKGND:
    21.            
    22.                 return TRUE;
     
  10. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Скорее всего в инфу включился расход на системные dll, которые в юзверьское АП подгружены.
    Попробуй мой анализатор состояния памяти для таких случаев - можешь вызвать его на старте и после "памяте-ёмких" действий сразу по разнице увидишь в твоей проге дело или система хулиганит :)
    Код (Text):
    1. // ============= Тестирование состояния памяти =============
    2. void memInfo(HWND hParentWnd){
    3.     TCHAR outStr[1024];
    4.     int p;
    5.     SYSTEM_INFO si;
    6.     MEMORY_BASIC_INFORMATION mbi;
    7.     UINT nBlocks = 0;
    8.     UINT nBlocksCommit = 0;
    9.     UINT nBlocksReserve = 0;
    10.     UINT nBlocksFree = 0;
    11.     UINT sizeCommit = 0;
    12.     UINT sizeReserve = 0;
    13.     UINT sizeFree = 0;
    14.     UINT const kb = 1024;
    15.     UINT const Mb = 1024*1024;
    16.     //-------------------------------------------------
    17.     GetSystemInfo(&si);
    18.     char  *pMem = (char*)si.lpMinimumApplicationAddress;
    19.     while (pMem < (char*)si.lpMaximumApplicationAddress){
    20.         nBlocks++;
    21.         VirtualQuery((char*)pMem, &mbi, sizeof mbi);
    22.         pMem += mbi.RegionSize;
    23.         switch (mbi.State){
    24.             case MEM_COMMIT:
    25.                 sizeCommit += mbi.RegionSize;
    26.                 nBlocksCommit++;
    27.                 break;  
    28.             case MEM_RESERVE:
    29.                 sizeReserve += mbi.RegionSize;
    30.                 nBlocksReserve++;
    31.                 break;  
    32.             case MEM_FREE:
    33.                 sizeFree += mbi.RegionSize;
    34.                 nBlocksFree++;
    35.         }
    36.     }
    37.     p = wsprintf(outStr, _T("Адресное пространство:\n\tначало:     %u\n\tконец:       %u\n\tстраница: %u\n"),
    38.         si.lpMinimumApplicationAddress, si.lpMaximumApplicationAddress, si.dwPageSize);
    39.     p += wsprintf(outStr + p, _T("Блоков памяти:\t%u шт.\nЗанято:\t\t%u кб\t\t(%u блоков)\t(%u страниц)\n"),
    40.         nBlocks, sizeCommit/kb, nBlocksCommit, sizeCommit/si.dwPageSize);
    41.     p += wsprintf(outStr + p, _T("Зарезервировано:\t%u кб\t\t(%u блоков)\t(%u страниц)\n"),
    42.         sizeReserve/kb, nBlocksReserve, sizeReserve/si.dwPageSize);
    43.     p += wsprintf(outStr + p, _T("Свободно:\t%u кб\t(%u блоков)\t(%u страниц)"),
    44.         sizeFree/kb, nBlocksFree, sizeFree/si.dwPageSize);
    45.     MessageBox(hParentWnd, outStr, _T("Cостояние памяти"), MB_OK);
    46.     return;
    47. }
     
  11. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    400*500*4=768кбайт. Плонировщик памяти обычно в 2 раза больше кушает

    4 мгбайта по дефолту хавается из-за базы кода.
     
  12. sometime

    sometime Odessa

    Публикаций:
    0
    Регистрация:
    22 апр 2009
    Сообщения:
    227
    Адрес:
    sunday
    ну пусть так оно и есть - тогда почему на 7-ке надо меньше памяти??? - вот это меня убивает больше всего) Планировщик что ли поумней написан....

    а на диске 3.98 Мб - асм форева!)

    Может чё в настройках студии мона поменять. Или по другому как то код писать?
     
  13. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    sometime #9
    Твои case действительно не содержат break'ов и return'ов или ты их сократил?
     
  14. sometime

    sometime Odessa

    Публикаций:
    0
    Регистрация:
    22 апр 2009
    Сообщения:
    227
    Адрес:
    sunday
    )) - урезал при копировании сюда - там снизу кучище коментов была...
     
  15. Z3N

    Z3N New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2009
    Сообщения:
    812
    Для предотвращения бликов окну можно было присвоить стиль WS_EXLAYERED (как точно пишется я не помню). Обычно убивает мигание намертво... :).
     
  16. sometime

    sometime Odessa

    Публикаций:
    0
    Регистрация:
    22 апр 2009
    Сообщения:
    227
    Адрес:
    sunday
    WS_EX_LAYERED - да спасиб!! Попробую, в предыдущем варианте пробовал с этим стилем сделать окно произвольной формы...но тут чёт не подумал:) А вобщем запустил на норм компе - все гуд не мерцает даже с обычным окном+ WS_POPUP .
     
  17. sometime

    sometime Odessa

    Публикаций:
    0
    Регистрация:
    22 апр 2009
    Сообщения:
    227
    Адрес:
    sunday
    Mikl___

    Еще одно спасибо!! Только что ,наконец решил забить на прозрачность(много проца поглащает к сожалению((. Начал все делать с начала и ессесно посмотрел что ты предложил - ОЧЕНЬ ДАЖЕ ЗАМЕЧАТЕЛЬНЫЙ ВАРИАНТ!
    +26% проца и то только на старте передвижений
    +напряга по выводу - "-1" ...все делает винда и я вообще не парюсь...
    осталось с кнопками разобратся - как я буду их рисовать - ща еще разок читану что там в уроках сказано ну и приму во внимание,а то уже много различных способов накапал и протэстил)

    к ста- не пойму я почему не работает тройная буфферизация?

    GetDC( hdc );
    hMemDC = CreateCompatibleDC( hdc );
    hSrcDC = CreateCompatibleDC( hdc );

    SelectObject( hSrcDC, hBgImg ); // тут я решил фоновую картинку положить в ДС
    BitBlt( hMemDC,.....,hSrcDC); // для того что бы потом было чем востанавливать фон
    // под кнопкой например

    BitBlt( hdc,....,hMemDC); //ну и двойная буферизация

    думал о CreateCompatibleBitmap - но так руки и не дошли(да и не особо понял зачем оно),а с Brush намного проще рисовать фон.

    ну вот и все,думаю что с рисованием разобрался)

    http://rsdn.ru/article/gdi/gdiplus2mag.xml#ECLAE - неплохая статья по GDI+ ,мож кому интересно будет.
     
  18. sometime

    sometime Odessa

    Публикаций:
    0
    Регистрация:
    22 апр 2009
    Сообщения:
    227
    Адрес:
    sunday
    Y_Mur
    представляешь - только что увидел твой пост:) - спасиб,попробую. Но уже как бы понял в чем заплёт,осталось проверить точно ли так)

    на XP SP2 ~5800kb
    XP SP3 ~5500kb
    Windows7 ~2000kb
    видать хрюхи нещадно с памятью поводятся))

    посмотрел)

    в криейте:
    Занято 18788 кб
    Зарезервировано 8608 кб
    Свободно 2069628 кб

    во время работы:
    Занято 19912 кб
    Зарезервировано 9560 кб
    Свободно 2067552 кб

    Прога с себя ничего не представляет - просто картинка в окне, которая (как я понимаю) загружена еще до криейта т.к. определена в виде PatternBrush в класе окна. По цифрам примерно понятно,но только примерно и особенно интересны цифры 19912кб - эт чё для моей проги столько понадобилось памяти???

    Ну и еще разок спасибо - полезная вещь!!!!!