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

Ваш аккаунт

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

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

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

Интересный вопрос по поводу связи таймера с WM_PAINT

318
09 января 2007 года
nof
193 / / 03.04.2006
Ребят, в общем есть две программы. Практически идентичны.
Различаются лишь обработчиком WM_PAINT.
Вот они:

/// ПРИМЕР НОМЕР 1
Код:
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM);
void CALLBACK TimerProc(HWND hWnd, UINT msg, UINT idTimer, DWORD dwTime);
LPCSTR szAppName  = "L";
HINSTANCE hInst;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine, int nCmdShow){
    HWND hWnd;
    MSG msg;
    WNDCLASS wc;

    hInst = hInstance;

    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WindowProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hCursor = LoadCursor(NULL,IDC_ARROW);
    wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
    wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    wc.lpszClassName = szAppName;
    wc.lpszMenuName = NULL;
    RegisterClass(&wc);
    hWnd = CreateWindow(szAppName,
        "L",
        WS_POPUPWINDOW ,//WS_OVERLAPPEDWINDOW,
        40, /* X-Position auf dem Monitor */
        40, /* Y-Position auf dem Monitor */
        300, /* Fensterbreite */
        300, /* Fensterhoehe */
        NULL,
        NULL,
        hInstance,
        NULL);

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
    while(1) {
            while(GetMessage(&msg,hWnd,0,0) == TRUE)
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        Sleep(50);
    }
    return 0;
}

LRESULT WINAPI WindowProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{

    switch(message)
    {
    case WM_LBUTTONDOWN:
        SetTimer(hWnd, 1, 1000, &TimerProc);
        break;

    case WM_PAINT:
        HDC hDC;

        hDC = GetDC(hWnd);
        TextOut(hDC, 5, 5, "HELLO WORLD", sizeof("HELLO WORLD"));
        ReleaseDC(hWnd, hDC);
        DeleteDC(hDC);
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        exit(0);
        break;
    default: return(DefWindowProc(hWnd,message,wParam,lParam));
        break;
    }
    return(0L);

}

void CALLBACK TimerProc(HWND hWnd, UINT msg, UINT idTimer, DWORD dwTime) {
    MessageBox (hWnd,"hello", "!!!", MB_OK);
    KillTimer(hWnd, 1);
}






/// ПРИМЕР НОМЕР 2
Код:
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM);
void CALLBACK TimerProc(HWND hWnd, UINT msg, UINT idTimer, DWORD dwTime);
LPCSTR szAppName  = "L";
HINSTANCE hInst;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine, int nCmdShow){
    HWND hWnd;
    MSG msg;
    WNDCLASS wc;

    hInst = hInstance;

    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WindowProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hCursor = LoadCursor(NULL,IDC_ARROW);
    wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
    wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    wc.lpszClassName = szAppName;
    wc.lpszMenuName = NULL;
    RegisterClass(&wc);
    hWnd = CreateWindow(szAppName,
        "L",
        WS_POPUPWINDOW ,//WS_OVERLAPPEDWINDOW,
        40, /* X-Position auf dem Monitor */
        40, /* Y-Position auf dem Monitor */
        300, /* Fensterbreite */
        300, /* Fensterhoehe */
        NULL,
        NULL,
        hInstance,
        NULL);

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    while(1) {
            while(GetMessage(&msg,hWnd,0,0) == TRUE)
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        Sleep(50);
    }
    return 0;
}

LRESULT WINAPI WindowProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
    switch(message)
    {
    case WM_LBUTTONDOWN:
        SetTimer(hWnd, 1, 1000, &TimerProc);
        break;
    case WM_PAINT:
        HDC hDC;
        PAINTSTRUCT PaintStruct;

        hDC = BeginPaint(hWnd,&PaintStruct);
        TextOut(hDC, 5, 5, "HELLO WORLD", sizeof("HELLO WORLD"));
        EndPaint(hWnd,&PaintStruct);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        exit(0);
        break;
    default: return(DefWindowProc(hWnd,message,wParam,lParam));
        break;
    }
    return(0L);

}

void CALLBACK TimerProc(HWND hWnd, UINT msg, UINT idTimer, DWORD dwTime) {
    MessageBox (hWnd,"hello", "!!!", MB_OK);
    KillTimer(hWnd, 1);
}



ВНИМАНИЕ ВОПРОС!
Почему в первом примере не работает таймер? И как собственно его заставить работать? Напомню, примеры отличаются лишь обрабоктой WM_PAINT.
247
09 января 2007 года
wanja
1.2K / / 03.02.2003
Что значит "не работает таймер"? Не рисует, что ли? Просто во втором случае сделано правильно.
5.9K
09 января 2007 года
Zushenskiy
161 / / 29.06.2006
Цитата:

HDC hDC;
hDC = GetDC(hWnd);
TextOut(hDC, 5, 5, "HELLO WORLD", sizeof("HELLO WORLD"));
ReleaseDC(hWnd, hDC);
DeleteDC(hDC);
break;


DeleteDC(hDC); - это не стой оперы


система какждый раз посылает WM_PAINT окну как появляеться невалидная зона окна то есть та которая требует перерисовки. после того как невалидная зона окна была перерисована ты должен сделать её валидной или система будет постоянно ставить в очередь сообщений окна сообщения WM_PAINT которое будет подвигать все сообщения почти фтопку. так вот пары функции BeginPaint и EndPaint делают валидность автоматом поетому очередь не захломляеться во втором примере. а впервом случае нужно дабавить функции ValidateRect кторая занимаеться валидностью

 
Код:
HDC hDC;
hDC = GetDC(hWnd);
TextOut(hDC, 5, 5, "HELLO WORLD", sizeof("HELLO WORLD"));
ReleaseDC(hWnd, hDC);
ValidateRect(hWnd, NULL);
318
09 января 2007 года
nof
193 / / 03.04.2006
Цитата: Zushenskiy
DeleteDC(hDC); - это не стой оперы


система какждый раз посылает WM_PAINT окну как появляеться невалидная зона окна то есть та которая требует перерисовки. после того как невалидная зона окна была перерисована ты должен сделать её валидной или система будет постоянно ставить в очередь сообщений окна сообщения WM_PAINT которое будет подвигать все сообщения почти фтопку. так вот пары функции BeginPaint и EndPaint делают валидность автоматом поетому очередь не захломляеться во втором примере. а впервом случае нужно дабавить функции ValidateRect кторая занимаеться валидностью
 
Код:
HDC hDC;
hDC = GetDC(hWnd);
TextOut(hDC, 5, 5, "HELLO WORLD", sizeof("HELLO WORLD"));
ReleaseDC(hWnd, hDC);
ValidateRect(hWnd, NULL);



Огромное спасибо! Разобрался!

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