Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.85
ElvenDragon
3 / 8 / 1
Регистрация: 12.07.2009
Сообщений: 361
#1

Функция обратного вызова - C++

26.08.2011, 10:34. Просмотров 1660. Ответов 4
Метки нет (Все метки)

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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#undef UNICODE
#include <windows.h>
#include "resource.h"
#include <iostream>
#include <fstream>
using namespace std;
 
HWND hWnd;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
 
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) {
  MSG SM; 
  WNDCLASSEX P;
  P.cbSize = sizeof(WNDCLASSEX);
  P.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
  P.lpfnWndProc = WndProc;
  P.cbClsExtra = 0;
  P.cbWndExtra = 0;
  P.hInstance = hInstance;
  P.hIcon = (HICON)LoadImage(hInstance,MAKEINTRESOURCE(IDI_j ),IMAGE_ICON,32,32,0);
  P.hCursor = (HCURSOR)LoadImage(hInstance, IDC_ARROW,IMAGE_CURSOR,32,32,LR_DEFAULTCOLOR);
  P.hbrBackground = CreateSolidBrush(RGB(255,0,0));
  P.lpszMenuName = 0;
  P.lpszClassName = "Tor";
  P.hIconSm = 0;
  if(!RegisterClassEx(&P)) {
    MessageBox(NULL,"Не правильно зарегестрирован класс окна","Ошибка",MB_OK);
    return 0;
  }
  hWnd = CreateWindowEx(0,"Tor","Respect",WS_OVERLAPPEDWINDOW,500,200,500,300,NULL,NULL,hInstance,NULL);
  if(!hWnd) {
    MessageBox(NULL,"Не правильно создано окно","Ошибка",MB_OK);
    return 0;
  }
  ShowWindow(hWnd,nCmdShow);  
  while(GetMessage(&SM,NULL,0,0)) { 
    TranslateMessage(&SM); 
    DispatchMessage(&SM); 
  }
   
  return SM.wParam;
} 
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
  const int ras = 1000;
  static int wClient;
  static int hClient;
  static int xPos;
  static int yPos;
  static int i = 0;
  static int f = 0;
  static char si[ras];
  static int m1 = 0;
  static ofstream m("C:\\S.txt");
  HDC  HDc;
  PAINTSTRUCT P;
  static RECT R, S;
  S.right = 100;
  S.bottom = 265;
  int yes;
  switch (message) { 
    case WM_PAINT:
      if(m1 > 0) m.open("C:\\S.txt");
      HDc = BeginPaint(hWnd,&P);
      GetClientRect(hWnd,&R);
      SetBkColor(HDc,RGB(255,0,0));
      SetTextColor(HDc,RGB(0,255,0));
      if(i != 0) DrawText(HDc, si, -1, &R,0);
      m << P.rcPaint.right << ' ' << P.rcPaint.bottom;
      m.close();
      m1++;
      EndPaint(hWnd,&P);
      break;
    case WM_DESTROY:
      PostQuitMessage(0);
      break;
    case WM_CLOSE:
      yes = MessageBox(hWnd,"Вы уверены в своем желании закрыть приложение?","Вопрос?",MB_YESNOCANCEL | MB_ICONQUESTION);
      if(IDYES == yes) DestroyWindow(hWnd);
      break;
    case WM_CHAR:
     
      if(wParam == 0x8) si[--i] = '\0';
      else if(i < ras-1) {
        si[i] = wParam;
        i++;
      }
      else MessageBox(hWnd,"Вы вышли за пределы массива","Ошибка",MB_OK);
      InvalidateRect(hWnd,&S,TRUE);
      break;
    case WM_SIZE:
      wClient = LOWORD(lParam);
      hClient = HIWORD(lParam);
      break;
    case WM_MOUSEMOVE:
      xPos = LOWORD(lParam);
      yPos = HIWORD(lParam);
      if(yPos > hClient - 50) SetCursor(LoadCursor(GetModuleHandle(NULL),MAKEINTRESOURCE(IDC_TOR)));
      else SetCursor(LoadCursor(NULL,IDC_ARROW));
    case WM_KEYDOWN:
       
      if(wParam == VK_RIGHT) {
        for(int x = i; x > f; x--) si[x] = si[x-1]; 
        si[f] = ' ';
        f++,i++;
      }
      else if(wParam == VK_LEFT) {
        int r = sizeof(si)-1;
        for(int x = --f; x < r; x++) si[x] = si[x+1];
        si[r] = '\0';
        i--;
      }
      InvalidateRect(hWnd,&S,TRUE);
      break;
    default:
      return DefWindowProc(hWnd, message, wParam, lParam);
  }
  return 0;
}
Почему в функции обратного вызова (WndProc) переменную типа (RECT S) надо объявлять статической?
Да я знаю что она сохраняет значение ,но всё же почему её нельзя там объявить как локальную? То есть можно ,но почему - то когда я ее инициализирую размеры 100 и 265 её полям не присваиваются почему так? Что нельзя при создании локальной переменной инициализировать её каждый раз как в обычной функции там все работает. Так почему же в обычной можно ,а функции обратного вызова нельзя?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.08.2011, 10:34
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Функция обратного вызова (C++):

оформить решение в виде функции следующими способами: 1. функция расположена после ее вызова; 2. функция расположена после до ее вызова; 3. функ - C++
оформить решение в виде функции следующими способами: 1. функция расположена после ее вызова; 2. функция расположена после до ее...

нужно чтобы функция располагалась до ее вызова, после ее вызова и в другом файле. Как это сделать? - C++
#include &lt;iostream&gt; #include &lt;conio.h&gt; using namespace std; int n, *c; void fun(int a, int b) { for (int i = 0; i &lt;...

Стрелка в описании функции обратного вызова - C++
#include &lt;iostream&gt; #include &lt;algorithm&gt; std::string s = &quot;hello&quot;; auto end = std::unique(s.begin(), s.end(), (char a, char b) -&gt; bool...

Заменить делегаты функциями обратного вызова - C++
public event EventHandler&lt;EventClientArgs&gt; OnNewClient; /// &lt;summary&gt; /// Обработка добавления нового клиента -...

Передача функций обратного вызова как членов некоторого класса - C++
Пытаюсь понемногу изучать OpenGL, и вот сейчас столкнулся с такой проблемой: Имеется некоторый класс, содержащий вектор и пару...

Нужна рабочая функция быстрого/прямого и обратного преобразования Фурье - C++
Нужна рабочая функция быстрого/прямого и обратного преобразования Фурье. В гугле много всего, рабочего не нашел.

4
alex_x_x
бжни
2447 / 1652 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
26.08.2011, 11:02 #2
callback не есть какая-та необычная функция - все обыкновенные правила должны и для нее работать
0
ValeryLaptev
Эксперт С++
1041 / 820 / 48
Регистрация: 30.04.2011
Сообщений: 1,659
26.08.2011, 11:54 #3
ElvenDragon, возможно дело в передаче параметра?
C++
1
InvalidateRect(hWnd,&S,TRUE);
Здесь передается адрес S. S - в стеке, если она локальная не статическая. То есть, в функцию Invalidate() передается адрес элемента стека оконной процедуры.
Я не знаю подробностей, как формируется стек при вызове оконной процедуры.
0
alex_x_x
бжни
2447 / 1652 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
26.08.2011, 11:58 #4
ValeryLaptev, я както тоже думал, что связано с временем жизни, но так по коду не видно - все вызовы
синхронные
надо отлаживать, так не очевидно
1
Сыроежка
Заблокирован
26.08.2011, 20:09 #5
Это просто плохой код! Так что не ломайте голову. На самом деле просто тот, программист, который писал этот код, очень ленивый, и не хотел для этого прямоугольника 'S', задать верхнюю и левую точки, то есть, если я правильно их называю, S.left и S.top.

Когда 'S' задана как static, то S.left и S.top устанавливаются равными 0.

На мой взгляд было бы проще написать

Rect S( 0, 0, 100, 265 );

то есть объявить S как локальную переменную, и сразу же ее инициализировать.

Вопрос только в том, как здесь было уже замечано, меняет ли эти значения функция InvalidateRect(hWnd,&S,TRUE);
Если она меняет, то конечно нужно объявить как stsatic.

static Rect S;

То есть в вашем коде, как я понял, важно сохранить координаты верхнего левого угла прямоугольника. Наверное именно поэтому эта переменная и объявлена как static. То есть при нажатии клавиши WM_KEYDOWN происходит смещение изображения в клиентской части.

Но в вашем конкретном случае это не имеет смысла! Вы могли бы объявить эту переменную как локальную, инициализировав ее так, как я указал.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.08.2011, 20:09
Привет! Вот еще темы с ответами:

Функция для вызова других функций - C++
короч нужна функция, которая принимала какое либо значения к примеру интовое, и в зависимости от значения вызывала бы другие функции) я...

После вызова первого пункта меню функция не возвращает введенную строку - C++
Очень нужна помощь людей с мозгами и желательно еще пояснения. Программа после вызова первого пункта меню не принимает строку,что делать?...

Функция, которая изменяет первоначальное значение переменной и хранит его до следующего вызова - C++
Нужно , чтобы функция(пусть даже main()) изменял первоначальное значение переменной и хранила его до следующего вызова. Кто может...

Нейронные сети обратного распространения - C++
Здравствуйте. Пытаюсь обучить сеть таблице умножения. Обучает до 1*3, а дальше не получается у него. Подскажите в чем беда. class...


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

Или воспользуйтесь поиском по форуму:
5
Yandex
Объявления
26.08.2011, 20:09
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru