Форум программистов, компьютерный форум, киберфорум
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. Показов 6142. Ответов 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
33398 / 21508 / 8236
Регистрация: 22.10.2011
Сообщений: 36,906
Записей в блоге: 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
33398 / 21508 / 8236
Регистрация: 22.10.2011
Сообщений: 36,906
Записей в блоге: 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
Ответ Создать тему
Новые блоги и статьи
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru