С Новым годом! Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.90/30: Рейтинг темы: голосов - 30, средняя оценка - 4.90
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,705

Не могу отправить окну сообщение WM_PAINT (точнее, не могу перерисовать окно)

17.01.2013, 11:14. Показов 6074. Ответов 18
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Смотрите оконную функцию она в самом низу. Всё остальное шаблонный код по созданию окна.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include <windows.h>
#include <stdio.h>
 
 
LRESULT CALLBACK WndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
 
char ClassName       []= "SimpleWinClass";
char AppName         []= "Our First Window";
char OurText         []= "Win32 assembly is great and easy!";
 
 
//У айзелиона это есть, а тут оказалось ненужным
//Но по идее не нужны, но оставлю уж
HINSTANCE hInstance;
LPSTR CommandLine;
 
//+++++++++++++++++++++++++++++++++
 
int WINAPI WinMain (HINSTANCE hInst,
                    HINSTANCE hPrevInst,
                    LPSTR CmdLine,
                    int CmdShow)
 
{
 
 hInstance= hInst;
 CommandLine= CmdLine;
 
 //структуры
 WNDCLASSEX wc;
 MSG msg;
 HWND hwnd;
 
 //инициализация;
 wc.cbSize= sizeof (WNDCLASSEX);
 wc.style= CS_HREDRAW | CS_VREDRAW;
 wc.lpfnWndProc= WndProc;
 wc.cbClsExtra= 0;
 wc.cbWndExtra= 0;
 wc.hInstance= hInst;
 wc.hbrBackground= (HBRUSH)(COLOR_WINDOW+1);
 wc.lpszMenuName= 0;
 wc.lpszClassName= ClassName;
 wc.hIcon= LoadIcon (NULL,IDI_APPLICATION);
 wc.hIconSm= 0;
 wc.hCursor= LoadCursor (NULL,IDC_ARROW);
 
 
 RegisterClassEx (&wc);
 
 hwnd= CreateWindowEx (0, ClassName,AppName,\
           WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
           CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
           hInst,NULL);
 
 ShowWindow (hwnd,SW_SHOWNORMAL);
 UpdateWindow (hwnd);
 
 
 
 while (true) {
   if (!GetMessage (&msg,NULL,0,0))
     break;
    TranslateMessage (&msg);
    DispatchMessage  (&msg);
 }
 return msg.wParam;
}
 
//+++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++
//Оконая функция
LRESULT CALLBACK WndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  static int i= 0;
  HDC hdc;
PAINTSTRUCT ps;
RECT rect;
  
  if (uMsg==WM_DESTROY) 
      PostQuitMessage (0);
  else if (uMsg==WM_PAINT) {
      printf ("%d\n", i);
      hdc= BeginPaint (hWnd, &ps);
      GetClientRect (hWnd, &rect);
      DrawText (hdc, &OurText[i++],-1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
      EndPaint (hWnd, &ps);
      UpdateWindow (hWnd);
  }
  else 
      return DefWindowProc (hWnd,uMsg,wParam,lParam );      
  return 0;
}
НУ и чё это за отрисовка? Я создаю консольное приложение, наряду с окном показывается консоль. Я вожу окном туда-сюда по рабочему столу, а оно ни фига не перерисовывается! Как была изначальная надпись так и остаётся. Если окно скрыть чем-нибудь, а потом снова показать- надпись изменится, да. Но такая отрисовка мне даром не нужна. Мне надо чтобы на моих глазах явно отрисовывалось, как задумываю.

Спасибо, кто откликнется.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
17.01.2013, 11:14
Ответы с готовыми решениями:

не могу отправить сообщение
Здравствуйте! Пытаюсь написать чат на С под Linux. Имеется клиент и сервер. В клиенте вводится сообщения и отправляется на сервер, а сервер...

Отправить сообщение окну
Нужно отправить сообщение о нажатие левой кнопки мыши окну Spy++ при клике в окно показывает следующее: 00A0626 S WM_MOUSEACTIVATE...

VkApi / Vk.Net - Не могу отправить сообщение
Не могу отправить сообщение using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; ...

18
Brainsbreaker
 Аватар для Digit@ll
899 / 374 / 54
Регистрация: 01.02.2011
Сообщений: 1,608
17.01.2013, 13:45
Тебе нужна бегущая строка? Тогда WM_PAINT не подойдет, как по мне. Ближе к вечеру постродаю с этим, если чё.
0
2838 / 1647 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
17.01.2013, 14:24
i слишком быстро выходит за пределы строки, а старый текст нигде не стирается. А так всё более-менее.
И UpdateWindow просто вызывает WndProc с WM_PAINT, если есть неперерисованные части, так что в обработчике WM_PAINT он точно не нужен.
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33371 / 21497 / 8234
Регистрация: 22.10.2011
Сообщений: 36,893
Записей в блоге: 12
17.01.2013, 14:59
Цитата Сообщение от Somebody Посмотреть сообщение
А так всё более-менее.
За исключением того, что WM_PAINT не отсылается окну, пока оно не изменит размеры или не перекроется другим окном. Посему при простом таскании окно обновляться не будет, пока не обработано WM_MOVING, с вызовом в его обработчике InvalidateRect.
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,705
17.01.2013, 15:50  [ТС]
Цитата Сообщение от Somebody Посмотреть сообщение
И UpdateWindow просто вызывает WndProc с WM_PAINT, если есть неперерисованные части, так что в обработчике WM_PAINT он точно не нужен.
поторопился с этим, согласен. Вызов UpdateWindow прост сводится к посылке WM_PAINT, как я понял.

Цитата Сообщение от UI Посмотреть сообщение
что WM_PAINT не отсылается окну, пока оно не изменит размеры или не перекроется другим окном
неправда ваша. Если бы WM_PAINT не посылалсь окну, я бы спросил- почему WM_PAINT не отсылается. В том-то и дело, что отсылается. Вы потаскайте, потаскайте окно ПОВЕРХ других окон поинтенсивнее за рамку. Только проект пусть будет консольным. Очень неплохо видно счётчик обработчиков вызовов WM_PAINT

Короче всё решилось так:

C++
1
2
3
4
5
6
7
8
9
  else if (uMsg==WM_PAINT) {
      printf ("%d\n", i);
      InvalidateRect (hWnd, NULL, true);
      hdc= BeginPaint (hWnd, &ps);
      GetClientRect (hWnd, &rect);
      DrawText (hdc, &OurText[i++],-1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
      EndPaint (hWnd, &ps);
      UpdateWindow (hWnd);
  }
Тупо вставил вызов InvalidateRect (hWnd, NULL, true); и всё на этом.
Но на самом деле это фигня, я это сделал неосмысленнно, я угадал. Почему я вижу это решение корявым? А вот:
"Функция InvalidateRect или InvalidateRgn может косвенно генерировать сообщения WM_PAINT для Ваших окон."
Понимаете, то есть я в обработчике WM_PAINT вызываю InvalidateRect, которая в свою очередь, отправляет WM_PAINT, в обработчике которого вызывается InvalidateRect, которая в свою очередь отправляет WM_PAINT, в обработчике которого вызывается...

Короче, как у меня стек не рушится- непонятно.
0
2838 / 1647 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
17.01.2013, 16:59
Цитата Сообщение от kravam Посмотреть сообщение
Понимаете, то есть я в обработчике WM_PAINT вызываю InvalidateRect, которая в свою очередь, отправляет WM_PAINT, в обработчике которого вызывается InvalidateRect, которая в свою очередь отправляет WM_PAINT, в обработчике которого вызывается...
Вообще WM_PAINT в большинстве случаев не посылается непосредственно в очередь, а вместо этого ставится флажок, при наличии которого и отсутствии сообщений в очереди генерируется WM_PAINT.
(Аналогично, например, WM_QUIT: если после PostQuitMessage послать ещё какое-то сообщение, то оно обработается до WM_QUIT.)
Цитата Сообщение от kravam Посмотреть сообщение
Короче, как у меня стек не рушится- непонятно.
И даже если бы оно шло прямо в очередь, то тогда проблемы были бы с очередью, а не со стеком - тут же рекурсии нет.
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33371 / 21497 / 8234
Регистрация: 22.10.2011
Сообщений: 36,893
Записей в блоге: 12
17.01.2013, 17:26
Цитата Сообщение от kravam Посмотреть сообщение
Вы потаскайте, потаскайте окно ПОВЕРХ других окон поинтенсивнее за рамку.
И чего я вижу после двухминутного таскания, (если только не вылез за границы десктопа, соответственно, окно частично скрыто, и потом, когда оно заново отображается полностью, и его надо обновить)? А вот что: в консольном окне один-единственный ноль как был, так и есть.

Так что не надо вот этих вот догадок. Я знаю, как оно работает. Если задан стиль CS_HREDRAW | CS_VREDRAW - то сообщения не приходят при простом перемещении окна. Сделай размеры окошка в CreateWindow поменьше (скажем, 300x150, чтоб случайно не вылететь), и затаскайся по десктопу, ни одного WM_PAINT-а не увидишь...
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,705
17.01.2013, 20:26  [ТС]
Ну хорошо, пусть окну не посылается WM_PAINT когда оно не не посылается. Согласен.

Фактически вы научили меня как таскать окно, чтобы к нему не приходили WM_PAINT и как таскать окно, чтобы к нему приходили WM_PAINT. Спасибо, за науку, а как на счёт вопроса?

Итак, таскаем окно, чтобы к нему приходили WM_PAINT- просто заводя его за края декстопа. Ну вот, собсно и всё. Вопрос- как сделать чтобы при отрисовке оно отрисовалось. То есть я задумываю при каждой обработке WM_PAINT уменьшить строчку на один символ, а не получается. От чего ушли к тому и пришли.

Я нашёл какой-то там способ (выше описал), но хотелось бы всё же осмысленное что-нибудь.
0
2838 / 1647 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
17.01.2013, 22:01
А, забыл сказать. При использовании BeginPaint + EndPaint перерисовываются только те части окна, которые надо перерисовать, остальные отсекаются. Если угол окна был загорожен другим окном, то от перерисовки текста в середине результата не будет, потому что эта часть окна не была "испорчена".
Общая логика такая: событие, которое меняет какие-то данные, вызывает InvalidateRect, а получившийся WM_PAINT перерисовывает всё, что надо.
1
Brainsbreaker
 Аватар для Digit@ll
899 / 374 / 54
Регистрация: 01.02.2011
Сообщений: 1,608
17.01.2013, 22:02
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
char OurText         []= "Win32 assembly is great and easy!   ";
 
LRESULT CALLBACK WndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    static int i=0;
    HDC hdc = GetWindowDC (hWnd);
    static RECT rect;
 
    if (uMsg == WM_CREATE)
    {
        SetRect (&rect, 290, 250, 500, 270);
        SetTimer (hWnd, 1, 200, 0);
    }
    else if (uMsg==WM_DESTROY)
        PostQuitMessage (0);
    else if (uMsg == WM_TIMER)
    {
        DrawText (hdc, &OurText[i++], -1, &rect, DT_SINGLELINE | DT_VCENTER);
        if (i == lstrlen(OurText))
        {
            KillTimer (hWnd, 1);
            ReleaseDC (hWnd, hdc);
        }
    }
    else 
        return DefWindowProc (hWnd,uMsg,wParam,lParam );      
    return 0;
}
0
2838 / 1647 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
17.01.2013, 22:09
Digit@ll, GetWindowDC - всегда, а ReleaseDC - в if'е - не айс.

Добавлено через 3 минуты
Да и отрисовывать по WM_TIMER не очень хорошо, потому что если потом будет WM_PAINT, то он или затрёт всё, или в нём придётся писать тот же самый DrawText...
0
Brainsbreaker
 Аватар для Digit@ll
899 / 374 / 54
Регистрация: 01.02.2011
Сообщений: 1,608
17.01.2013, 22:17
Да, возможно, я думал об этом, тогда добавь и ему статичности. И оставьте уже WM_PAINT, он безобидный, если его не трогать.
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,705
17.01.2013, 22:24  [ТС]
Somebody,
Тогда я угадал с этим кодом.
C++
1
2
3
4
5
6
7
8
9
else if (uMsg==WM_PAINT) {
      printf ("%d\n", i);
      InvalidateRect (hWnd, NULL, true);
      hdc= BeginPaint (hWnd, &ps);
      GetClientRect (hWnd, &rect);
      DrawText (hdc, &OurText[i++],-1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
      EndPaint (hWnd, &ps);
      UpdateWindow (hWnd);
  }
Чё хотел, то и получил.
событие, которое меняет какие-то данные, вызывает InvalidateRect, а получившийся WM_PAINT перерисовывает всё, что надо.
0
Brainsbreaker
 Аватар для Digit@ll
899 / 374 / 54
Регистрация: 01.02.2011
Сообщений: 1,608
18.01.2013, 00:38
Ну и kravam, сам себя хвалит. У-ха-ха.
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,705
18.01.2013, 08:02  [ТС]
Я бы по-другому это назвал. Делаю выводы о правильности или неправильности своего решения.
0
Brainsbreaker
 Аватар для Digit@ll
899 / 374 / 54
Регистрация: 01.02.2011
Сообщений: 1,608
18.01.2013, 11:47
Я это к тому, что у тебя мутотень в коде. Но по-правде сказать мне эта возня надоела, давай уже что-то новое.
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,705
18.01.2013, 12:49  [ТС]
Это код Айзелиона, если ты знаешь, кто это такой. И я добавил туда лишь
C++
1
InvalidateRect (hWnd, NULL, true);
и изменение строки.
Убирается на раз. Ты не этого не сделал потому, что ты не умеешь. Тебе проще сказать "мутотень" нежели попытаться исправить- а это делается, потворю ОЧЕНЬ ЛЕГКО. Да и не факт, что править надо.

Вердикт: мутотень у меня в коде всяко лучше чем мутотень у тебя в голове.
0
21.01.2013, 13:19

Не по теме:

Да, золотые слова. Пусть мутотень будет у тебя в кодах, чем у меня в голове. Всех благ.

0
21.01.2013, 13:32  [ТС]

Не по теме:

Цитата Сообщение от Digit@ll Посмотреть сообщение
Пусть мутотень будет у тебя в кодах, чем у меня в голове.
не пойдёт. Пусть у тебя в голове будет мутотень, а у меня в кодах не будет. Привет.

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
21.01.2013, 13:32
Помогаю со студенческими работами здесь

Не могу отправить сообщение на почту mail.ru
Не могу отправить сообщение с помощью SMTP. У меня стоит 10 версия indy. Также на форму кинул компоненты Idsmtp, idmessage. На форме есть...

Отправить сообщение окну из программы-сервиса
Есть обычное оконное приложение, работающее под пользовательской учетной записью, и программа сервис, работающая под системной учеткой....

Помогите с MFC. Не могу разобраться с WM_PAINT
Здраствуйте. Если я провожу по окну своей программы другим окном то стираются все кнопки, поля ввода и тд, кроме картинки, которую я...

Не могу отправить сообщение по Winsock компу с русским именем
Такая пробелема: есть например, программа NetTalk (слава создателю) для общения по локальной сети. Пытаюсь сделать что-то подобное на VB....

Не могу перерисовать панели
Спасайте! Написал прогу, рисующие рандомные треугольники с рандомными цветами на 7 панелей (по одному треугольнику на панели): using...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Новые блоги и статьи
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru