Аха, утечка есть. Чтобы её устранить, после BitBlt в WM_PAINT необходимо прочесть заклятия Код (Text): DeleteDC(hMemDC) а после него Код (Text): DeleteObject(hBitm)
Правильно смущает - в данном случае это значит, что, фактически, переменная является глобальной Но видима она только внутри одной функции. Т.е. всё нормально там. glukker Насчёт утечки - Booster советовал создавать hMemDC и hBitm при принятии WM_CREATE же. И, соответственно, освобождать при уничтожении окна. Это будет более лучше, чем создавать и удалять их при принятии WM_COMMAND и WM_PAINT.
Если я так делаю так: Код (Text): case WM_PAINT: { hdc = BeginPaint(hwnd, &ps); BitBlt (hdc, 0, 0, iWinX, iWinY, hMemDC, 0, 0, SRCCOPY); //DeleteDC(hMemDC); //DeleteObject(hBitm); EndPaint(hwnd, &ps); } break; то все усилия сводятся на нет... В том смысле, что после таких добавлений текст затирается... Так что после BitBlt в WM_PAINT наверное не надо добавлять DeleteDC(hMemDC) и DeleteObject(hBitm)...
Вот поправил... Вроде всё как надо... Код (Text): LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; static HDC hMemDC; static HBITMAP hBitm; HBRUSH hBrush; RECT Rect; switch(message) { case WM_CREATE: { hdc = GetDC (hwnd); hMemDC = CreateCompatibleDC (hdc); hBitm = CreateCompatibleBitmap (hdc, iWinX, iWinY); }break; case WM_PAINT: { hdc = BeginPaint(hwnd, &ps); BitBlt (hdc, 0, 0, iWinX, iWinY, hMemDC, 0, 0, SRCCOPY); EndPaint(hwnd, &ps); } break; case WM_COMMAND: switch (LOWORD(wParam)) { case BN_CLICKED: if (hButton == (HWND)lParam) { SelectObject (hMemDC, hBitm); hBrush = CreateSolidBrush (0xFFFFFF); SetRect (&Rect, 0, 0, iWinX, iWinY); FillRect (hMemDC, &Rect, hBrush); TextOut(hMemDC, 10, 120, "1234567890", 10); InvalidateRect(hwnd, NULL, true); } }break; case WM_DESTROY: ReleaseDC (hwnd, hdc); DeleteDC (hdc); PostQuitMessage(0); break; default: return DefWindowProc(hwnd, message, wParam, lParam); } return 0; }
Да и: Код (Text): SelectObject (hMemDC, hBitm); hBrush = CreateSolidBrush (0xFFFFFF); Надо перенести в WM_CREATE, сделав hBrush - static. И SetRect(&Rect, 0, 0, iWinX, iWinY); наверно можно выполнить всего один раз.
Всё... точно сказал можно... ОГРОМНОЕ Спасибо всем участникам... Особенно Booster'у!!! Код (Text): LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; static HDC hMemDC; static HBITMAP hBitm; static HBRUSH hBrush; RECT Rect; switch(message) { case WM_CREATE: { hdc = GetDC (hwnd); hMemDC = CreateCompatibleDC (hdc); hBitm = CreateCompatibleBitmap (hdc, iWinX, iWinY); SelectObject (hMemDC, hBitm); hBrush = CreateSolidBrush (0xFFFFFF); SetRect (&Rect, 0, 0, iWinX, iWinY); FillRect (hMemDC, &Rect, hBrush); }break; case WM_PAINT: { hdc = BeginPaint(hwnd, &ps); BitBlt (hdc, 0, 0, iWinX, iWinY, hMemDC, 0, 0, SRCCOPY); EndPaint(hwnd, &ps); } break; case WM_COMMAND: switch (LOWORD(wParam)) { case BN_CLICKED: if (hButton == (HWND)lParam) { TextOut(hMemDC, 10, 120, "1234567890", 10); InvalidateRect(hwnd, NULL, true); } }break; case WM_DESTROY: ReleaseDC (hwnd, hdc); DeleteDC (hMemDC); DeleteObject (hBrush); PostQuitMessage(0); break; default: return DefWindowProc(hwnd, message, wParam, lParam); } return 0; }
Кстати ещё небольшой вопросик... Раньше загружал BMP - рисунок из ресурсов в окошко так... Где нибудь в начале функции WinMain писал так: Код (Text): HBITMAP hBitmap; hBitmap = (HBITMAP)LoadImage (hThisInst, MAKEINTRESOURCE(IDB_BITMAP_1), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); А затем в обработчике WM_PAINT делал так: Код (Text): BITMAP bm; HDC hDC; HDC hMemDC; HBITMAP hBmp; case WM_PAINT: { hdc = BeginPaint(hwnd, &ps); hBmp = LoadBitmap( hInst, "BITMAP1" ); GetObject( hBmp, sizeof( BITMAP ), &bm ); hDC = GetDC( hWnd ); hMemDC = CreateCompatibleDC( hDC ); SelectObject( hMemDC, hBmp ); BitBlt( hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY ); EndPaint(hwnd, &ps); } break; Собственно вопрос для загрузки BMP в окошку нужно проводить в WM_CREATE теже операции для BMP-рисунка, т.е. сначала (GetDC, CreateCompatibleDC, SelectObject) с другими параметрами или можно тоже запихнуть в созданый hMemDC созданный для перерисовки? Тем более что BitBlt у меня уже есть в WM_PAINT для перерисовке...
Можно сделать ещё один временный DC, провернуть для него все операции (GetDC, CreateCompatibleDC, SelectObject), загрузить битмап из ресурса, выбрать его для этого DC. И когда надо, вызывать BitBlt с таргетом hMemDC, и источником hBitmDC. Это позволит выводить картинку на любой участок hMemDC. Можно и выбрать загруженную картинку для hMemDC, хотя это и не всегда подходит. Как понимаю ты это и имел ввиду. Ну и конечно создаём всё это один раз по приходу WM_CREATE, в WM_PAINT только BitBlt, а в WM_COMMAND рисуем, пишем.
Я вот только не совсем понял раз в WM_PAINT только один раз вызывается: Код (Text): BitBlt( hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY ); то выходит нужно запихивать изображение в hMemDC... два раза вызывать BitBlt (с различными параметрами) в WM_PAINT будет нелогично?
Да конечно, нужно создать отдельный контекст устройства с картинкой по приходу события WM_CREATE. Затем по нажатию кнопки скопировать контекст с картинкой на контекст заднего буфера, с помощью BitBlt, написать текст. А в WM_PAINT вызываем BitBlt для копирования заднего на передний.
Ага спасибо ещё раз всё получилось!!! Скачал книжечку по интерфейсу средствами WinAPI буду читать... Скажите Booster, а вы пробовали делать какие нибудь сложные элементы интерфейса?
Что имеется под сложными? Если обычные виндовые, то на этом сайте тоже есть по ним туторы. Если кастомные навороченные, то нет. Проще воспользоваться готовыми библиотеками, например с помощью Xtreme Toolkit Pro можно сделать интерфейс как в офисе или вижал студии, но она платная.
Не вообще всегда было интересно узнать как например днлают ComboBox c иконками внутри списка... тоесть иконка слева, а напротив текст... В литературе не нашел.... Пишут в основном про фундаментальные окна...
Уже нашёл и скачал Xtreme Toolkit Pro v11.2.2 с ключом в комплекте... Правда это же MFC ( я его не люблю на красотища...
Подскажите что делаю не так... Когда загружаю рисунок 1.bmp он нормально отображается, меняю на 2.bmp компилирую остается тоже самый рисунок, хотя в действительности он другой... Код (Text): case WM_COMMAND: switch (LOWORD(wParam)) { case BN_CLICKED: if (hButton == (HWND)lParam) { hBitmapLoad = (HBITMAP) LoadImage(NULL, "2.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); GetObject (hBitmapLoad, sizeof (BITMAP), &BitmapInfo); SelectObject (hBitmapLoadDC, hBitmapLoad); BitBlt (hMemDC, 255, 10, BitmapInfo.bmWidth, BitmapInfo.bmHeight, hBitmapLoadDC, 0, 0, SRCCOPY); TextOut(hMemDC, 10, 120, "1234567890", 10); InvalidateRect(hwnd, NULL, true); } }break;
Помню у меня было, что то похожее. Возникает какой-то косяк и все линкуется со старыми OBJ файлами. Убей ручками все OBJ и промежуточные файлики. Может поможет.