Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

отображение .bmp-файла в окне

54K
10 декабря 2009 года
ChuckNorris.attack()
6 / / 09.12.2009
Добрый день! Захотелось написать такую программу. Нашёл в сети вот эту статью, переделал её под С++ и ещё немного изменил, чтобы картинка открывалась прямо с диска, а не из ресурсов. Но программа не работает. Запускается, открывается пустое окно, видно, что жрёт процессор почти на 100%, и ничего видимого не делает.
Вот код:
Код:
#include <windows.h>

/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/*  Make the class name into a global variable  */
char szClassName[ ] = "CodeBlocksWindowsApp";

char fname[100];


int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nCmdShow)
{
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default colour as the background of the window */
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;

    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           "Code::Blocks Template Windows App",       /* Title Text */
           WS_OVERLAPPEDWINDOW, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           544,                 /* The programs width */
           375,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );

    /* Make the window visible on the screen */
    ShowWindow (hwnd, nCmdShow);
    UpdateWindow(hwnd);
    strcpy(fname,"D:\h.bmp");
    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }

    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}


/*  This function is called by the Windows function DispatchMessage()  */

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{

    PAINTSTRUCT ps;
    HDC hDC;
    HDC hMemDC;
    HBITMAP bmp_file;
    RECT rect;
    switch (message)                  /* handle the messages */
    {
        case WM_CREATE:
        {
            break;
        }
        case WM_DESTROY:
        {
            DeleteObject(bmp_file);
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
            break;
        }
        case WM_PAINT:
        {
            hDC = BeginPaint(hwnd, &ps);
            hMemDC = CreateCompatibleDC(hDC);
            bmp_file = (HBITMAP)LoadImage(NULL, fname, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);
            SelectObject(hMemDC,bmp_file);
            GetClientRect(hwnd,&rect);
            BitBlt(hDC,0,0,rect.right,rect.bottom,hMemDC,0,0,SRCCOPY);
            DeleteDC(hMemDC);
            EndPaint(hwnd, &ps);
            break;
        }
        default:                      /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}

Кстати, если LoadImage поставить прямо в описании переменной: вот так: HBITMAP bmp_file = LoadImage(... то картинка отображается, но при этом где-то образуется страшная утечка памяти - через 10 секунд процесс жрёт уже 300мб, и увеличивается. Подскажите пожалуйста, что тут куда?
14
10 декабря 2009 года
Phodopus
3.3K / / 19.06.2008
bmp_file =
надо поставить перед CreateWindowEx()
или в WM_CREATE (переменную в любом случае глобальную или статическую)
54K
10 декабря 2009 года
ChuckNorris.attack()
6 / / 09.12.2009
Сделал, всё-равно картинка не показывается... Код:
Код:
#include <windows.h>

/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/*  Make the class name into a global variable  */
char szClassName[ ] = "CodeBlocksWindowsApp";

char fname[100];
PAINTSTRUCT ps;
HDC hDC;
HDC hMemDC;
HBITMAP bmp_file;
RECT rect;

int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nCmdShow)
{
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default colour as the background of the window */
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;
    bmp_file = (HBITMAP)LoadImage(NULL, fname, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);
    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           "Code::Blocks Template Windows App",       /* Title Text */
           WS_OVERLAPPEDWINDOW, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           544,                 /* The programs width */
           375,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );

    /* Make the window visible on the screen */
    ShowWindow (hwnd, nCmdShow);
    UpdateWindow(hwnd);
    strcpy(fname,"D:\h.bmp");
    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }

    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}


/*  This function is called by the Windows function DispatchMessage()  */

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{


    switch (message)                  /* handle the messages */
    {
        case WM_CREATE:
        {

            break;
        }
        case WM_DESTROY:
        {
            DeleteObject(bmp_file);
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
            break;
        }
        case WM_PAINT:
        {
            hDC = BeginPaint(hwnd, &ps);
            hMemDC = CreateCompatibleDC(hDC);
            SelectObject(hMemDC,bmp_file);
            GetClientRect(hwnd,&rect);
            BitBlt(hDC,0,0,rect.right,rect.bottom,hMemDC,0,0,SRCCOPY);
            DeleteDC(hMemDC);
            EndPaint(hwnd, &ps);
            break;
        }
        default:                      /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}


Всё, работает, спасибо !! Я просто забыл строчку strcpy(fname,"D:\h.bmp"); поставить выше, чем LoadImage(параметры) (я ведь эту строчку переместил)
54K
10 декабря 2009 года
ChuckNorris.attack()
6 / / 09.12.2009
Теперь другой вопрос: как определить размер битмапа, загруженного с помощью LoadImage? Имеется ввиду ширина и высота.
14
11 декабря 2009 года
Phodopus
3.3K / / 19.06.2008
SelectObject() перед DeleteDC() надо делать обратно. Иначе будет потихоньку отжираться память.
Цитата: ChuckNorris.attack()
как определить размер битмапа, загруженного с помощью LoadImage? Имеется ввиду ширина и высота.


насколько я помню, GetObject()

7
11 декабря 2009 года
@pixo $oft
3.4K / / 20.09.2006
Цитата: Phodopus
SelectObject() перед DeleteDC() надо делать обратно. Иначе будет потихоньку отжираться память

А в чём смысл сей тайной манипуляции(ну это я так,для себя,вдруг пригодится)?
И что должно быть в аргументах SelectObject()?

54K
11 декабря 2009 года
ChuckNorris.attack()
6 / / 09.12.2009
Всё, нашёл способ! GetObject действительно нужен. Эта функция заполняет структуру типа BITMAP, объект которой нужно перед этим инициализировать(Например BITMAP bmpInfo).А затем - после GetObject делаем bmpInfo.bmHeight и bmpInfo.bmWidth. Сделал прогу, которую хотел!:)
Отображает bmp, и подстраивает размеры окна под этот битмап:) Чтобы работало надо запхнуть картинку в корень D: и назвать h.bmp. Пока так... как-бы тестовый вариант
Код:
#include <windows.h>

/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/*  Make the class name into a global variable  */
char szClassName[ ] = "CodeBlocksWindowsApp";

char fname[100];
PAINTSTRUCT ps;
HDC hDC;
HDC hMemDC;
HBITMAP bmp_file;
RECT rect;
BITMAP bmpInfo;
int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nCmdShow)
{
    HWND hwnd;
    MSG messages;
    WNDCLASSEX wincl;


    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;
    wincl.style = CS_DBLCLKS;
    wincl.cbSize = sizeof (WNDCLASSEX);
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;
    wincl.cbClsExtra = 0;
    wincl.cbWndExtra = 0;
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
    if (!RegisterClassEx (&wincl))
        return 0;
    hwnd = CreateWindowEx (
           0,
           szClassName,
           "Code::Blocks Template Windows App",
           WS_OVERLAPPEDWINDOW,
           CW_USEDEFAULT,
           CW_USEDEFAULT,
           544,
           375,
           HWND_DESKTOP,
           NULL,
           hThisInstance,
           NULL
           );
    ShowWindow (hwnd, nCmdShow);
    UpdateWindow(hwnd);
    while (GetMessage (&messages, NULL, 0, 0))
    {
        TranslateMessage(&messages);
        DispatchMessage(&messages);
    }
    return messages.wParam;
}
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_CREATE:
        {
            strcpy(fname,"D:\h.bmp");
            bmp_file = (HBITMAP)LoadImage(NULL, fname, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);
            GetObject(bmp_file, sizeof(BITMAP), &bmpInfo);
            SetWindowPos(hwnd,HWND_TOP,rect.top,rect.left,bmpInfo.bmWidth,bmpInfo.bmHeight,SWP_SHOWWINDOW);
            break;
        }
        case WM_DESTROY:
        {
            DeleteObject(bmp_file);
            PostQuitMessage (0);
            break;
        }
        case WM_PAINT:
        {
            hDC = BeginPaint(hwnd, &ps);
            hMemDC = CreateCompatibleDC(hDC);
            SelectObject(hMemDC,bmp_file);
            GetClientRect(hwnd,&rect);
            BitBlt(hDC,0,0,rect.right,rect.bottom,hMemDC,0,0,SRCCOPY);
            DeleteDC(hMemDC);
            EndPaint(hwnd, &ps);
            break;
        }
        default:
            return DefWindowProc (hwnd, message, wParam, lParam);
    }
    return 0;
}
14
11 декабря 2009 года
Phodopus
3.3K / / 19.06.2008
Цитата: @pixo $oft
А в чём смысл сей тайной манипуляции(ну это я так,для себя,вдруг пригодится)?
И что должно быть в аргументах SelectObject()?


Смысл - отдать контексту то что у него было изначально, так принято и так правильно. В аргументах, в данном случае, то что возвращает первый SelectObject().

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог