Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 21.10.2011, 14:59   #1
БалаШагаЛ
Форумчанин
 
Регистрация: 11.02.2011
Сообщений: 131
По умолчанию InvalidateRect() и LPCRECT

Помогите, пожалуйста, новичку.
Как я понял, функция InvalidateRect() позволяет стереть содержимое прямоугольника в окне. Её второй параметр - прямоугольник типа LPCRECT. Если он равен NULL, то стирается всё окно.
Так вот, как сделать его не NULL? Ведь, как я понял, LPCRECT - это практически указатель на тип CONST RECT. То есть это константа, которую нельзя изменять на протяжении программы. Как тогда придать значения свойствам rect, left, top и bottom? Компилятор ругается на изменение константы!
БалаШагаЛ вне форума Ответить с цитированием
Старый 21.10.2011, 15:03   #2
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

вообще то это константный указатель на тип RECT
что означает что данные через указатель не будут изменены.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 21.10.2011, 16:06   #3
haruhi
Форумчанин
 
Аватар для haruhi
 
Регистрация: 05.10.2011
Сообщений: 368
По умолчанию

cоздать обычную переменную RECT и передать указатель на неё в функцию InvalidateRect
Не стоит будить спящего Бога! (с) Меланхолия Харухи Судзумии
haruhi вне форума Ответить с цитированием
Старый 21.10.2011, 17:59   #4
БалаШагаЛ
Форумчанин
 
Регистрация: 11.02.2011
Сообщений: 131
По умолчанию

Так я пытался так делать. Вот код.
Код:
#include "windows.h"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <math.h>
#include <string.h>
#include <time.h>

int a=250;

LRESULT CALLBACK WindowFunc(HWND,UINT,UINT,LONG);

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszCmdParam,int nCmdShow)
{
    WNDCLASS WndClass;
    HWND hWnd;
    MSG Msg;
    char szWndClassName[]="WndClass";
    WndClass.style=CS_VREDRAW|CS_HREDRAW;
    WndClass.cbClsExtra=0;
    WndClass.cbWndExtra=0;
    WndClass.hInstance=hInstance;
    WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
    WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
    WndClass.lpfnWndProc=WindowFunc;
    WndClass.hbrBackground=(HBRUSH)(LTGRAY_BRUSH);
    WndClass.lpszClassName=szWndClassName;
    WndClass.lpszMenuName=NULL;
    if (!RegisterClass(&WndClass))
    {
        MessageBox(NULL,"Window class error!","ERROR!",MB_OK);
        return 0;
    }
    hWnd=CreateWindow(szWndClassName,
                      "Окно",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      NULL,NULL,
                      hInstance,NULL);
    if (!hWnd)
    {
        MessageBox(NULL,"Window error!","ERROR!",MB_OK);
        return 0;
    }
    ShowWindow(hWnd,SW_MAXIMIZE);
    UpdateWindow(hWnd);
    while(GetMessage(&Msg,NULL,0,0))
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}

LRESULT CALLBACK WindowFunc(HWND hWnd,UINT Message,UINT wParam,LONG IParam)
{
    HDC hDC;
    PAINTSTRUCT PaintStruct;
    RECT *Rect;
    switch(Message)
    {
        case WM_LBUTTONUP:
        {
        a+=10;
        GetClientRect(hWnd,Rect);
        InvalidateRect(hWnd,Rect,TRUE);
        hDC=BeginPaint(hWnd,&PaintStruct);
        Rectangle(hDC,50,50,a,150);
        EndPaint(hWnd,&PaintStruct);
        return 0;
        }
        case WM_PAINT:
        hDC=BeginPaint(hWnd,&PaintStruct);
        Rectangle(hDC,50,50,a,150);
        EndPaint(hWnd,&PaintStruct);
        return 0;
        case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hWnd,Message,wParam,IParam);
}
Компилируется и запускается нормально, но при нажатии левой кнопки мыши в окне выскакивает ошибка от Windows (где отправить отсчёт/не отправлять). Что делать? Что не так в этом коде?
БалаШагаЛ вне форума Ответить с цитированием
Старый 21.10.2011, 18:11   #5
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

а где у вас данные на которые указатель указывает?
обьявили указатель, думаете он будет волшебным?
учите основы про указатели и операцию взяимя указателя.
Код:
LRESULT CALLBACK WindowFunc(HWND hWnd,UINT Message,UINT wParam,LONG IParam)
{
    HDC hDC;
    PAINTSTRUCT PaintStruct;
    RECT Rect;//до этого писалось в никуда, теперь будет писаться в эту структуру.
    switch(Message)
    {
        case WM_LBUTTONUP:
        {
        a+=10;
        GetClientRect(hWnd,&Rect);//передаем указатель на нее
        InvalidateRect(hWnd,&Rect,TRUE);//и тут.
        hDC=BeginPaint(hWnd,&PaintStruct);
        Rectangle(hDC,50,50,a,150);
        EndPaint(hWnd,&PaintStruct);
        return 0;
        }
        case WM_PAINT:
        hDC=BeginPaint(hWnd,&PaintStruct);
        Rectangle(hDC,50,50,a,150);
        EndPaint(hWnd,&PaintStruct);
        return 0;
        case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hWnd,Message,wParam,IParam);
}
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 21.10.2011, 23:37   #6
БалаШагаЛ
Форумчанин
 
Регистрация: 11.02.2011
Сообщений: 131
По умолчанию

Так я вроде создавал указатель и передавал его в функции. Адрес и указатель - это вроде одно и тоже... Да, с указателями, признаюсь, у меня проблема, хотя до сих пор думал, что работать с ними умею.
Всё получилось. Спасибо большое всем за помощь!
БалаШагаЛ вне форума Ответить с цитированием
Старый 22.10.2011, 10:15   #7
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
Адрес и указатель - это вроде одно и тоже...
ну да.
Цитата:
Так я вроде создавал указатель и передавал его в функции.
дык, а указывает указатель на что? куда то там, но не структуру RECT.(а функции именно она и нужна)
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 23.10.2011, 00:26   #8
An1ka
C++,DirectX/OpenGL
Форумчанин
 
Регистрация: 09.01.2011
Сообщений: 422
По умолчанию

Цитата:
Сообщение от БалаШагаЛ Посмотреть сообщение
Так вот, как сделать его не NULL? Ведь, как я понял, LPCRECT - это практически указатель на тип CONST RECT. То есть это константа, которую нельзя изменять на протяжении программы. Как тогда придать значения свойствам rect, left, top и bottom? Компилятор ругается на изменение константы!
const в аргументе функции значит, что данные по указателю будут доступны для данной функции только для чтения.
Функция как бы говорит нам: "Я буду использовать ваши данные по указателю только для чтения ! Trust me !". А нам остается лишь поверить ей на слово ! Ибо в C++ полно хаков способных обойти этот модификатор : const_cast, mutable и тд.
An1ka вне форума Ответить с цитированием
Старый 23.10.2011, 14:45   #9
Rififi
Старожил
 
Регистрация: 19.08.2009
Сообщений: 2,119
По умолчанию

Цитата:
Сообщение от БалаШагаЛ Посмотреть сообщение
Ведь, как я понял, LPCRECT - это практически указатель на тип CONST RECT.

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
вообще то это константный указатель на тип RECT
что означает что данные через указатель не будут изменены.
Вы таки удивитесь, но правильный ответ - у автора ((((Ж
LPCRECT - это указатель на константный объект RECT

что означает что данные через указатель не будут изменены

А теперь - правильный ответ: :D

данные на которые указывает константный указатель, менять можно. А само значение указателя - нет.
Rififi вне форума Ответить с цитированием
Старый 24.12.2013, 12:29   #10
mestnyi
 
Регистрация: 18.01.2012
Сообщений: 3
По умолчанию

Цитата:
Всё получилось
А у вас гаджеты на форме не дергаются когда используете "InvalidateRect("
mestnyi вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Перерисовка окна при момощи InvalidateRect assch Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 2 01.07.2011 19:49
Мерцание, перепрорисовка не всей формы,InvalidateRect... Lelya-perinya Мультимедиа в Delphi 5 11.12.2010 07:56
Перерисовать окно InvalidateRect где указывать delias Win Api 2 25.03.2010 01:15