Перерисовка окна...

Тема в разделе "WASM.BEGINNERS", создана пользователем glukker, 8 июл 2008.

  1. glukker

    glukker New Member

    Публикаций:
    0
    Регистрация:
    14 фев 2008
    Сообщения:
    72
    Правда может у меня есть какая - нибудь утечка ресурсов...
    Если есть подскажите...
     
  2. DEEP

    DEEP Андрей

    Публикаций:
    0
    Регистрация:
    27 апр 2008
    Сообщения:
    491
    Адрес:
    г. Владимир
    Аха, утечка есть. Чтобы её устранить, после BitBlt в WM_PAINT необходимо прочесть заклятия
    Код (Text):
    1. DeleteDC(hMemDC)
    а после него

    Код (Text):
    1. DeleteObject(hBitm)
     
  3. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    Правильно смущает - в данном случае это значит, что, фактически, переменная является глобальной ;)
    Но видима она только внутри одной функции. Т.е. всё нормально там.

    glukker
    Насчёт утечки - Booster советовал создавать hMemDC и hBitm при принятии WM_CREATE же. И, соответственно, освобождать при уничтожении окна. Это будет более лучше, чем создавать и удалять их при принятии WM_COMMAND и WM_PAINT.
     
  4. glukker

    glukker New Member

    Публикаций:
    0
    Регистрация:
    14 фев 2008
    Сообщения:
    72
    Если я так делаю так:
    Код (Text):
    1.         case WM_PAINT:
    2.             {
    3.                 hdc = BeginPaint(hwnd, &ps);
    4.                
    5.                 BitBlt (hdc, 0, 0, iWinX, iWinY, hMemDC, 0, 0, SRCCOPY);
    6.                 //DeleteDC(hMemDC);
    7.                 //DeleteObject(hBitm);
    8.  
    9.                 EndPaint(hwnd, &ps);
    10.             } break;
    то все усилия сводятся на нет... В том смысле, что после таких добавлений текст затирается...
    Так что после BitBlt в WM_PAINT наверное не надо добавлять DeleteDC(hMemDC) и DeleteObject(hBitm)...
     
  5. glukker

    glukker New Member

    Публикаций:
    0
    Регистрация:
    14 фев 2008
    Сообщения:
    72
    Вот поправил... Вроде всё как надо...
    Код (Text):
    1. LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    2. {
    3.     PAINTSTRUCT ps;
    4.     HDC hdc;
    5.     static HDC hMemDC;
    6.     static HBITMAP hBitm;
    7.  
    8.     HBRUSH hBrush;
    9.     RECT Rect;
    10.  
    11.     switch(message)
    12.     {
    13.         case WM_CREATE:
    14.             {
    15.                 hdc = GetDC (hwnd);
    16.                 hMemDC = CreateCompatibleDC (hdc);     
    17.                 hBitm = CreateCompatibleBitmap (hdc, iWinX, iWinY);
    18.             }break;
    19.  
    20.         case WM_PAINT:
    21.             {
    22.                 hdc = BeginPaint(hwnd, &ps);
    23.                
    24.                 BitBlt (hdc, 0, 0, iWinX, iWinY, hMemDC, 0, 0, SRCCOPY);
    25.  
    26.                 EndPaint(hwnd, &ps);
    27.             } break;
    28.  
    29.         case WM_COMMAND:
    30.             switch (LOWORD(wParam))
    31.             {
    32.                 case BN_CLICKED:
    33.                     if (hButton == (HWND)lParam)
    34.                         {
    35.                             SelectObject (hMemDC, hBitm);
    36.  
    37.                             hBrush = CreateSolidBrush (0xFFFFFF);
    38.                             SetRect (&Rect, 0, 0, iWinX, iWinY);
    39.                             FillRect (hMemDC, &Rect, hBrush);
    40.  
    41.                             TextOut(hMemDC, 10, 120, "1234567890", 10);
    42.                            
    43.                             InvalidateRect(hwnd, NULL, true);              
    44.  
    45.                         }
    46.             }break;
    47.  
    48.         case WM_DESTROY:
    49.             ReleaseDC (hwnd, hdc);
    50.             DeleteDC (hdc);
    51.  
    52.             PostQuitMessage(0);
    53.             break;
    54.  
    55.         default:
    56.                 return DefWindowProc(hwnd, message, wParam, lParam);
    57.     }
    58.         return 0;
    59. }
     
  6. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Да и:
    Код (Text):
    1. SelectObject (hMemDC, hBitm);
    2. hBrush = CreateSolidBrush (0xFFFFFF);
    Надо перенести в WM_CREATE, сделав hBrush - static.

    И SetRect(&Rect, 0, 0, iWinX, iWinY); наверно можно выполнить всего один раз.
     
  7. glukker

    glukker New Member

    Публикаций:
    0
    Регистрация:
    14 фев 2008
    Сообщения:
    72
    Всё...
    точно сказал можно...
    ОГРОМНОЕ Спасибо всем участникам... Особенно Booster'у!!!
    Код (Text):
    1. LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    2. {
    3.     PAINTSTRUCT ps;
    4.     HDC hdc;
    5.     static HDC hMemDC;
    6.     static HBITMAP hBitm;
    7.     static HBRUSH hBrush;
    8.  
    9.     RECT Rect;
    10.  
    11.     switch(message)
    12.     {
    13.         case WM_CREATE:
    14.             {
    15.                 hdc = GetDC (hwnd);
    16.                 hMemDC = CreateCompatibleDC (hdc);     
    17.                 hBitm = CreateCompatibleBitmap (hdc, iWinX, iWinY);
    18.  
    19.                 SelectObject (hMemDC, hBitm);
    20.                 hBrush = CreateSolidBrush (0xFFFFFF);
    21.  
    22.                 SetRect (&Rect, 0, 0, iWinX, iWinY);
    23.                 FillRect (hMemDC, &Rect, hBrush);
    24.             }break;
    25.  
    26.         case WM_PAINT:
    27.             {
    28.                 hdc = BeginPaint(hwnd, &ps);
    29.                
    30.                 BitBlt (hdc, 0, 0, iWinX, iWinY, hMemDC, 0, 0, SRCCOPY);
    31.  
    32.                 EndPaint(hwnd, &ps);
    33.             } break;
    34.  
    35.         case WM_COMMAND:
    36.             switch (LOWORD(wParam))
    37.             {
    38.                 case BN_CLICKED:
    39.                     if (hButton == (HWND)lParam)
    40.                         {
    41.                             TextOut(hMemDC, 10, 120, "1234567890", 10);
    42.                             InvalidateRect(hwnd, NULL, true);              
    43.  
    44.                         }
    45.             }break;
    46.  
    47.         case WM_DESTROY:
    48.             ReleaseDC (hwnd, hdc);
    49.             DeleteDC (hMemDC);
    50.             DeleteObject (hBrush);
    51.  
    52.             PostQuitMessage(0);
    53.             break;
    54.  
    55.         default:
    56.                 return DefWindowProc(hwnd, message, wParam, lParam);
    57.     }
    58.         return 0;
    59. }
     
  8. glukker

    glukker New Member

    Публикаций:
    0
    Регистрация:
    14 фев 2008
    Сообщения:
    72
    Кстати ещё небольшой вопросик... Раньше загружал BMP - рисунок из ресурсов в окошко так...
    Где нибудь в начале функции WinMain писал так:
    Код (Text):
    1. HBITMAP hBitmap;
    2. hBitmap = (HBITMAP)LoadImage (hThisInst, MAKEINTRESOURCE(IDB_BITMAP_1), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
    А затем в обработчике WM_PAINT делал так:
    Код (Text):
    1. BITMAP bm;
    2. HDC hDC;
    3. HDC hMemDC;
    4. HBITMAP hBmp;
    5.  
    6. case WM_PAINT:
    7.     {
    8.         hdc = BeginPaint(hwnd, &ps);
    9.                
    10.                       hBmp = LoadBitmap( hInst, "BITMAP1" );
    11.                       GetObject( hBmp, sizeof( BITMAP ), &bm );
    12.  
    13.                       hDC    = GetDC( hWnd );
    14.                       hMemDC = CreateCompatibleDC( hDC );
    15.                       SelectObject( hMemDC, hBmp );
    16.                       BitBlt( hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY );
    17.  
    18.         EndPaint(hwnd, &ps);
    19.     } break;
    Собственно вопрос для загрузки BMP в окошку нужно проводить в WM_CREATE теже операции для BMP-рисунка, т.е. сначала (GetDC, CreateCompatibleDC, SelectObject) с другими параметрами или можно тоже запихнуть в созданый hMemDC созданный для перерисовки?
    Тем более что BitBlt у меня уже есть в WM_PAINT для перерисовке...
     
  9. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Можно сделать ещё один временный DC, провернуть для него все операции (GetDC, CreateCompatibleDC, SelectObject), загрузить битмап из ресурса, выбрать его для этого DC. И когда надо, вызывать BitBlt с таргетом hMemDC, и источником hBitmDC. Это позволит выводить картинку на любой участок hMemDC. Можно и выбрать загруженную картинку для hMemDC, хотя это и не всегда подходит. Как понимаю ты это и имел ввиду.

    Ну и конечно создаём всё это один раз по приходу WM_CREATE, в WM_PAINT только BitBlt, а в WM_COMMAND рисуем, пишем.
     
  10. glukker

    glukker New Member

    Публикаций:
    0
    Регистрация:
    14 фев 2008
    Сообщения:
    72
    Я вот только не совсем понял раз в WM_PAINT только один раз вызывается:
    Код (Text):
    1. BitBlt( hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY );
    то выходит нужно запихивать изображение в hMemDC...
    два раза вызывать BitBlt (с различными параметрами) в WM_PAINT будет нелогично?
     
  11. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Да конечно, нужно создать отдельный контекст устройства с картинкой по приходу события WM_CREATE. Затем по нажатию кнопки скопировать контекст с картинкой на контекст заднего буфера, с помощью BitBlt, написать текст. А в WM_PAINT вызываем BitBlt для копирования заднего на передний.
     
  12. glukker

    glukker New Member

    Публикаций:
    0
    Регистрация:
    14 фев 2008
    Сообщения:
    72
    Ага спасибо ещё раз всё получилось!!!
    Скачал книжечку по интерфейсу средствами WinAPI буду читать...
    Скажите Booster, а вы пробовали делать какие нибудь сложные элементы интерфейса?
     
  13. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Что имеется под сложными? Если обычные виндовые, то на этом сайте тоже есть по ним туторы. Если кастомные навороченные, то нет. Проще воспользоваться готовыми библиотеками, например с помощью Xtreme Toolkit Pro можно сделать интерфейс как в офисе или вижал студии, но она платная.
     
  14. glukker

    glukker New Member

    Публикаций:
    0
    Регистрация:
    14 фев 2008
    Сообщения:
    72
    Не вообще всегда было интересно узнать как например днлают ComboBox c иконками внутри списка...
    тоесть иконка слева, а напротив текст... В литературе не нашел.... Пишут в основном про фундаментальные окна...
     
  15. glukker

    glukker New Member

    Публикаций:
    0
    Регистрация:
    14 фев 2008
    Сообщения:
    72
    Уже нашёл и скачал Xtreme Toolkit Pro v11.2.2 с ключом в комплекте...
    Правда это же MFC :dntknw:( я его не люблю на красотища...
     
  16. glukker

    glukker New Member

    Публикаций:
    0
    Регистрация:
    14 фев 2008
    Сообщения:
    72
    Подскажите что делаю не так...
    Когда загружаю рисунок 1.bmp он нормально отображается, меняю на 2.bmp компилирую остается тоже самый рисунок, хотя в действительности он другой...
    Код (Text):
    1.         case WM_COMMAND:
    2.             switch (LOWORD(wParam))
    3.             {
    4.                 case BN_CLICKED:
    5.                     if (hButton == (HWND)lParam)
    6.                         {
    7.                             hBitmapLoad = (HBITMAP) LoadImage(NULL, "2.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    8.                             GetObject (hBitmapLoad, sizeof (BITMAP), &BitmapInfo);
    9.                             SelectObject (hBitmapLoadDC, hBitmapLoad);
    10.                             BitBlt (hMemDC, 255, 10, BitmapInfo.bmWidth, BitmapInfo.bmHeight, hBitmapLoadDC, 0, 0, SRCCOPY);
    11.                             TextOut(hMemDC, 10, 120, "1234567890", 10);
    12.                             InvalidateRect(hwnd, NULL, true);              
    13.  
    14.                         }
    15.             }break;
     
  17. S_Alex

    S_Alex Alex

    Публикаций:
    0
    Регистрация:
    27 авг 2004
    Сообщения:
    561
    Адрес:
    Ukraine
    Помню у меня было, что то похожее.
    Возникает какой-то косяк и все линкуется со старыми OBJ файлами.
    Убей ручками все OBJ и промежуточные файлики. Может поможет.